![MQL5を使ったシンプルな多通貨エキスパートアドバイザーの作り方(第2回):指標シグナル:多時間枠放物線SAR指標](https://c.mql5.com/2/58/Parabolic_SAR_MTF_600x314.jpg)
MQL5を使ったシンプルな多通貨エキスパートアドバイザーの作り方(第2回):指標シグナル:多時間枠放物線SAR指標
はじめに
この記事における多通貨EAの定義は、1つの銘柄チャートからのみ複数の銘柄ペアの取引(注文を出す、注文を決済する、注文を管理するなど)ができるEAまたは自動売買ロボットです。この記事では、EAは30ペアを取引します。今回は、PERIOD_M15からPERIOD_D1までの多時間枠でパラボリックSARまたはiSARという1つの指標のみを使用します。
取引ターミナルとストラテジーテスターの両方で、MQL5が提供するパワー、機能、能力を使用して複数通貨取引が可能であることは誰もが知っています。
そのため、この記事では、効率的で効果的な自動売買ロボットを求めるトレーダーの本質的なニーズを満たすことを目的とし、信頼性の高いMQL5が提供する長所、能力、機能に頼ることで、指標シグナルを使用するシンプルな多通貨EAを作成します。多時間枠パラボリックSARまたはiSAR指標です。
計画と機能
1.通貨ペアの取引
この多通貨EAは、以下の銘柄またはペアで取引するように計画されています。
外国為替:
EURUSD、GBPUSD、AUDUSD、NZDUSD、USDCAD、USDCHF、USDJPY、EURGBP、
EURAUD、EURNZD、EURCAD、EURCHF、EURJPY、 GBPAUD、GBPNZD、GBPCAD,
GBPCHF、GBPJPY、AUDNZD、AUDCAD、AUDCHF、AUDJPY、NZDCAD、NZDCHF、
NZDJPY、CADCHF、CADJPY、CHFJPY(計28ペア)
追加のメタル2ペア:XAUUSD(金)とXAGUSD(銀)
合計30ペア
注:これらの銘柄やペアはすべて、ブローカーが一般的に使用するものです。この多通貨EAは、接頭辞または接尾辞を持つ銘柄またはペア名を持つブローカーでは動作しません。
2.シグナル指標
多通貨EAは1つの指標シグナルを使用しますが、PERIOD_M15、PERIOD_M30、PERIOD_H1、PERIOD_H4、PERIOD_D1から始まる5つの時間枠を使用します。
このEAでは、指標シグナルの計算に固定時間枠を使用しないため、シグナル計算時間枠を決定する必要はありません。
これは、EA「FXSAR_MTF_MCEA」がPERIOD_M1からPERIOD_MN1までの任意の時間枠で使用でき、FXSAR_MTF_MCEAは依然としてiSARPERIOD_M15、PERIOD_M30、PERIOD_H1、PERIOD_H4、PERIOD_D1に基づいてシグナルを計算するということです。
これら5つのパラボリックSAR時間枠が出された注文のシグナルを決定します。
一方、シグナルが弱まったときに注文を決済するには、注文が利益状態にある場合にiSAR指標PERIOD_M15を使用します。
また、トレーリングストップとトレーリングプロフィットをおこなうには、iSAR指標PERIOD_H1を使用します。
iSARシグナル状態戦略の式:
UP=(PRICE_LOW[0] > iSARLine)または(PRICE_LOW[0] > iSAR[0])
DOWN=(PRICE-HIGH[0] < iSARLine)または(PRICE-HIGH[0] < iSAR[0])
買いシグナルまたは売りシグナルを取得する場所:
5つのiSAR指標の時間枠の合計が、買いの場合は5xUP、売りの場合はDOWNである必要があります。
iSAR指標untukBUYatauSELLを図1に示します。
3.取引と注文管理
この多通貨EAの取引管理には、いくつかのオプションが与えられています。
1.ストップロス注文
- オプション:Use Order Stop Loss:Yes/No
Use Order Stop LossでNoを選択すると、すべての注文はストップロスなしで発注されます。
Use Order Stop LossでYesを選択すると、オプションUse Automatic Calculation Stop LossでYes/Noを指定することになります。
Use Automatic Calculation Stop LossがYesの場合、ストップロスの計算はEAによって自動的に実行されます。
Automatic Calculation Stop LossがNoの場合、トレーダーはストップロス値をPipsで入力する必要があります。
Use Order Stop LossがNoの場合、開かれた各注文について、シグナル状態がまだ良好であるかどうかがEAによって確認され、注文されます。
利益を維持できるか、シグナルが弱まり、保存するには注文を決済する必要がある状態を維持できます。
利益またはシグナルの状態が方向を反転したため、注文は損失ポジションで決済する必要があります。
2.テイクプロフィット注文
- オプション:Use Order Take Profit:Yes/No
Use Order Take ProfitでNoを選択した場合、すべての注文はテイクプロフィットなしで発注されます。
Use Order Take ProfitでYesを選択した場合、さらにオプションUseAutomatic Calculation Order Take Profit:Yes/Noを指定することになります。
Automatic Calculation Order Take ProfitでYesを選択すると、テイクプロフィット注文の計算はEAで自動的におこなわれます。
Automatic Calculation Order Take ProfitでNoを選択すると、トレーダーはOrder Take Profit値をPipsで入力する必要があります。
3.トレーリングストップとトレーリングテイクプロフィット
- オプション:Use Trailing SL/TP:Yes/No
Use Trailing SL/TPがNoの場合、EAはトレーリングストップロスおよびトレーリングテイクプロフィットをおこないません。Use Trailing SL/TPオプションがYesの場合、さらに、オプションUse Automatic Trailing:Yes/Noで、Use Automatic TrailingでYesを選択すると、EAはパラボリックSAR値PERIOD_H1を使用してトレーリングストップを実行し、同時にTPmin(トレーリングプロフィット値)変数値に基づいてトレーリングプロフィットを得ることができます。Use Automatic TrailingでNoを選択すると、EAによってトレーリングストップが入力プロパティの値を使用して実行されます。
注:EAはトレーリングストップと同時にトレーリングテイクプロフィットを実行します。
4.手動注文管理
この多通貨EAの効率をサポートするために、いくつかの手動クリックボタンが追加されます。
1.Set SL / TP All Orders
トレーダーの入力パラメータがOrder Stop LossがNoおよび/またはUse Order Take ProfitがNoの場合
ただし、トレーダーがすべての注文でストップロスまたはテイクプロフィットを使用するつもりであれば、[Set SL / TP All Orders]ボタンを1回クリックするだけで、すべての注文が変更され、ストップロスが適用され、および/またはテイクプロフィットがおこなわれます。
2.Close All Orders
トレーダーがすべての注文を決済したい場合、[Close All Orders]ボタンを1回クリックするだけで、すべての未決注文が決済されます。
3.Close All Orders Profit
トレーダーがすでに利益が出ているすべての注文を決済したい場合は、[Close All Orders Profit]ボタンを1回クリックするだけで済みます。
その後、すでに利益を上げているすべての注文が決済されます。
5.管理注文と銘柄のチャート
1つのチャート銘柄から30ペアを取引する多通貨EAの場合、すべての銘柄にボタンパネルが用意されていれば、トレーダーはワンクリックでチャートや銘柄を変更でき、非常に効果的かつ効率的です。
MQL5プログラムでの実装計画
1.プログラムのヘッダーとプロパティの入力
ヘッダーファイルMQL5をインクルードします。
//+------------------------------------------------------------------+ //| Include | //+------------------------------------------------------------------+ #include <Trade\Trade.mqh> #include <Trade\PositionInfo.mqh> #include <Trade\SymbolInfo.mqh> #include <Trade\AccountInfo.mqh> //-- CTrade mc_trade; CSymbolInfo mc_symbol; CPositionInfo mc_position; CAccountInfo mc_account; //---
列挙体YNは、EA入力プロパティのオプション(YesまたはNo)に使用されます。
enum YN
{
No,
Yes
};
資金管理ロットサイズを使用する列挙
//-- enum mmt { FixedLot, // Fixed Lot Size DynamLot // Dynamic Lot Size }; //--
EA入力プロパティ:
//--- input group "=== Money Management Lot Size Parameter ==="; // Money Management Lot Size Parameter input mmt mmlot = DynamLot; // Money Management Type input double Risk = 10.0; // Percent Equity Risk per Trade (Min=1.0% / Max=10.0%) input double Lots = 0.01; // Input Manual Lot Size FixedLot //--Day Trading On/Off input group "=== Day Trading On/Off ==="; // Day Trading On/Off input YN ttd0 = No; // Select Trading on Sunday (Yes) or (No) input YN ttd1 = Yes; // Select Trading on Monday (Yes) or (No) input YN ttd2 = Yes; // Select Trading on Tuesday (Yes) or (No) input YN ttd3 = Yes; // Select Trading on Wednesday (Yes) or (No) input YN ttd4 = Yes; // Select Trading on Thursday (Yes) or (No) input YN ttd5 = Yes; // Select Trading on Friday (Yes) or (No) input YN ttd6 = No; // Select Trading on Saturday (Yes) or (No) //--Trade & Order management Parameter input group "=== Trade & Order management Parameter ==="; // Trade & Order management Parameter input YN use_sl = No; // Use Order Stop Loss (Yes) or (No) input YN autosl = Yes; // Use Automatic Calculation Stop Loss (Yes) or (No) input double SLval = 30; // If Not Use Automatic SL - Input SL value in Pips input YN use_tp = Yes; // Use Order Take Profit (Yes) or (No) input YN autotp = Yes; // Use Automatic Calculation Take Profit (Yes) or (No) input double TPval = 10; // If Not Use Automatic TP - Input TP value in Pips input YN TrailingSLTP = Yes; // Use Trailing SL/TP (Yes) or (No) input YN autotrl = Yes; // Use Automatic Trailing (Yes) or (No) input double TSval = 5; // If Not Use Automatic Trailing Input Trailing value in Pips input double TSmin = 5; // Minimum Pips to start Trailing Stop input double TPmin = 25; // Input Trailing Profit Value in Pips input YN Close_by_Opps = Yes; // Close Trade By Opposite Signal (Yes) or (No) input YN SaveOnRev = Yes; // Close Trade and Save profit due to weak signal (Yes) or (No) //--Others Expert Advisor Parameter input group "=== Others Expert Advisor Parameter ==="; // Others EA Parameter input YN alerts = Yes; // Display Alerts / Messages (Yes) or (No) input YN UseEmailAlert = No; // Email Alert (Yes) or (No) input YN UseSendnotify = No; // Send Notification (Yes) or (No) input YN trade_info_display = Yes; // Select Display Trading Info on Chart (Yes) or (No) input ulong magicEA = 2023102; // Expert ID (Magic Number) //---
この多通貨EAに必要なすべての変数、オブジェクト、関数を宣言するために、EAのワークフローにおける構築と構成を指定するクラスを作成します。
//+------------------------------------------------------------------+ //| Class for working Expert Advisor | //+------------------------------------------------------------------+ class MCEA { //--- private: //---- int x_year; // Year int x_mon; // Month int x_day; // Day of the month int x_hour; // Hour in a day int x_min; // Minutes int x_sec; // Seconds //-- int oBm, oSm, ldig; int posCur1, posCur2; //-- double LotPS; double slv, tpv, pip, xpip; double differ; double floatprofit, fixclprofit; //-- string pairs, hariini, daytrade, trade_mode; //-- double OPEN[], HIGH[], LOW[], CLOSE[]; datetime TIME[]; datetime closetime; //------------ int DirectionMove(const string symbol); int GetPSARSignalMTF(string symbol); int PARSAR05(const string symbol); int PARSARMTF(const string symbol,ENUM_TIMEFRAMES mtf); int LotDig(const string symbol); //-- double MLots(const string symbx); double NonZeroDiv(double val1,double val2); double OrderSLSet(const string xsymb,ENUM_ORDER_TYPE type,double atprice); double OrderTPSet(const string xsymb,ENUM_ORDER_TYPE type,double atprice); double SetOrderSL(const string xsymb,ENUM_POSITION_TYPE type,double atprice); double SetOrderTP(const string xsymb,ENUM_POSITION_TYPE type,double atprice); double TSPrice(const string xsymb,ENUM_POSITION_TYPE ptype,int TS_type); //-- string ReqDate(int d,int h,int m); string TF2Str(ENUM_TIMEFRAMES period); string timehr(int hr,int mn); string TradingDay(void); string AccountMode(); string GetCommentForOrder(void) { return(expname); } //------------ public: //-- FXSAR_MTF_MCEA Config -- string DIRI[], AS30[]; string expname; int hPar05[]; // Handle for the iSAR indicator for M5 Timeframe int hPSAR[][5]; // Handle Indicator, where each Symbol has 5 arrays for Timeframe starting from TF_M15 to TF_D1 int ALO, dgts, arrsar, arrsymbx; int sall, arper; ulong slip; //-- double SARstep, SARmaxi; double profitb[], profits[]; //-- int Buy, Sell; int ccur, psec, xtto, TFArrays, checktml; int OpOr[],xob[],xos[]; //-- int year, // Year mon, // Month day, // Day hour, // Hour min, // Minutes sec, // Seconds dow, // Day of week (0-Sunday, 1-Monday, ... ,6-Saturday) doy; // Day number of the year (January 1st is assigned the number value of zero) //-- ENUM_TIMEFRAMES TFt, TFT05, TFSAR[]; //-- bool PanelExtra; //------------ MCEA(void); ~MCEA(void); //------------ virtual void FXSAR_MTF_MCEA_Config(void); virtual void ExpertActionTrade(void); //-- void ArraySymbolResize(void); void CurrentSymbolSet(const string symbol); void Pips(const string symbol); void TradeInfo(void); void Do_Alerts(const string symbx,string msgText); void CheckOpenPMx(const string symbx); void SetSLTPOrders(void); void CloseBuyPositions(const string symbol); void CloseSellPositions(const string symbol); void CloseAllOrders(void); void CheckClose(const string symbx); void TodayOrders(void); void UpdatePrice(const string symbol,ENUM_TIMEFRAMES xtf); void RefreshPrice(const string symbx,ENUM_TIMEFRAMES xtf,int bars); //-- bool RefreshTick(const string symbx); bool TradingToday(void); bool OpenBuy(const string symbol); bool OpenSell(const string symbol); bool ModifyOrderSLTP(double mStop,double ordtp); bool ModifySLTP(const string symbx,int TS_type); bool CloseAllProfit(void); bool ManualCloseAllProfit(void); //-- int PairsIdxArray(const string symbol); int TFIndexArray(ENUM_TIMEFRAMES TF); int GetOpenPosition(const string symbol); int GetCloseInWeakSignal(const string symbol,int exis); int ThisTime(const int reqmode); //-- string getUninitReasonText(int reasonCode); //------------ //--- }; //-end class MCEA
OnInit()から呼び出される多通貨EAワークプロセスの最初で最も重要な関数は、FXSAR_MTF_MCEA_Config()です。
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit(void) { //--- mc.FXSAR_MTF_MCEA_Config(); //-- return(INIT_SUCCEEDED); //--- } //-end OnInit()
FXSAR_MTF_MCEA_Config()関数では、使用されるすべての銘柄が設定され、すべてのハンドル指標が使用され、EAワークフローのインクルードファイルヘッダーのいくつかの重要な関数が設定されます。
//+------------------------------------------------------------------+ //| Expert Configuration | //+------------------------------------------------------------------+ void MCEA::FXSAR_MTF_MCEA_Config(void) { //--- //-- string All30[]={"EURUSD","GBPUSD","AUDUSD","NZDUSD","USDCAD","USDCHF","USDJPY","EURGBP", "EURAUD","EURNZD","EURCAD","EURCHF","EURJPY","GBPAUD","GBPNZD","GBPCAD", "GBPCHF","GBPJPY","AUDNZD","AUDCAD","AUDCHF","AUDJPY","NZDCAD","NZDCHF", "NZDJPY","CADCHF","CADJPY","CHFJPY","XAUUSD","XAGUSD"}; // 30 pairs //-- sall=ArraySize(All30); ArrayResize(AS30,sall,sall); ArrayCopy(AS30,All30,0,0,WHOLE_ARRAY); //-- arrsymbx=sall; ArraySymbolResize(); ArrayCopy(DIRI,All30,0,0,WHOLE_ARRAY); for(int x=0; x<arrsymbx; x++) {SymbolSelect(DIRI[x],true);} pairs="Multi Currency 30 Pairs"; //-- TFT05=PERIOD_M5; ENUM_TIMEFRAMES TFA[]={PERIOD_M15,PERIOD_M30,PERIOD_H1,PERIOD_H4,PERIOD_D1}; TFArrays=ArraySize(TFA); ArrayResize(TFSAR,TFArrays,TFArrays); ArrayCopy(TFSAR,TFA,0,0,WHOLE_ARRAY); //-- TFt=TFSAR[2]; //-- //-- iSAR Indicators handle for all symbol for(int x=0; x<arrsymbx; x++) { hPar05[x]=iSAR(DIRI[x],TFT05,SARstep,SARmaxi); //-- Handle for the iSAR indicator for M5 Timeframe //-- for(int i=0; i<TFArrays; i++) { hPSAR[x][i]=iSAR(DIRI[x],TFSAR[i],SARstep,SARmaxi); // Handle for iSAR Indicator array sequence of the requested timeframe } } //-- ALO=(int)mc_account.LimitOrders()>arrsymbx ? arrsymbx : (int)mc_account.LimitOrders(); //-- LotPS=(double)ALO; //-- mc_trade.SetExpertMagicNumber(magicEA); mc_trade.SetDeviationInPoints(slip); mc_trade.SetMarginMode(); //-- return; //--- } //-end FXSAR_MTF_MCEA_Config()
2.EAティック関数
EAのティック関数(OnTick()関数)の中で、多通貨EAのメイン関数の1つである関数ExpertActionTrade()を呼び出します。
//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick(void) { //--- mc.ExpertActionTrade(); //-- return; //--- } //-end OnTick()
ExpertActionTrade()関数は、注文を出し、注文を決済し、トレイリングストップまたはトレイリングプロフィット、およびその他の追加アクティビティを実行し、自動売買を管理します。
操作の一連の流れは、以下のプログラムの傍らで私が説明した通りです。
void MCEA::ExpertActionTrade(void) { //--- //Check Trading Terminal ResetLastError(); //-- if(!MQLInfoInteger(MQL_TRADE_ALLOWED) && mc.checktml==0) //-- Check whether MT5 Algorithmic trading is Allow or Prohibit { mc.Do_Alerts(Symbol(),"Trading Expert at "+Symbol()+" are NOT Allowed by Setting."); mc.checktml=1; //-- Variable checktml is given a value of 1, so that the alert is only done once. return; } //-- if(!DisplayManualButton("M","C","R")) DisplayManualButton(); //-- Show the expert manual button panel //-- if(trade_info_display==Yes) mc.TradeInfo(); //-- Displayed Trading Info on Chart //--- //-- int mcsec=mc.ThisTime(mc.sec); //-- if(fmod((double)mcsec,5.0)==0) mc.ccur=mcsec; //-- if(mc.ccur!=mc.psec) { string symbol; //-- Here we start with the rotation of the name of all symbol or pairs to be traded for(int x=0; x<mc.arrsymbx && !IsStopped(); x++) { //-- if(mc.DIRI[x]==Symbol()) symbol=Symbol(); else symbol=mc.DIRI[x]; //-- mc.CurrentSymbolSet(symbol); //-- if(mc.TradingToday()) { //-- mc.OpOr[x]=mc.GetOpenPosition(symbol); //-- Get trading signals to open positions //-- //-- and store in the variable OpOr[x] if(mc.OpOr[x]==mc.Buy) //-- If variable OpOr[x] get result of GetOpenPosition(symbol) as "Buy" (value=1) { //-- mc.CheckOpenPMx(symbol); //-- if(Close_by_Opps==Yes && mc.xos[x]>0) mc.CloseSellPositions(symbol); //-- if(mc.xob[x]==0 && mc.xtto<mc.ALO) mc.OpenBuy(symbol); else if(mc.xtto>=mc.ALO) { //-- mc.Do_Alerts(symbol,"Maximum amount of open positions and active pending orders has reached"+ "\n the limit = "+string(mc.ALO)+" Orders "); //-- mc.CheckOpenPMx(symbol); //-- if(mc.xos[x]>0 && mc.profits[x]<-1.02 && mc.xob[x]==0) {mc.CloseSellPositions(symbol); mc.OpenBuy(symbol);} else if(SaveOnRev==Yes) mc.CloseAllProfit(); } } if(mc.OpOr[x]==mc.Sell) //-- If variable OpOr[x] get result of GetOpenPosition(symbol) as "Sell" (value=-1) { //-- mc.CheckOpenPMx(symbol); //-- if(Close_by_Opps==Yes && mc.xob[x]>0) mc.CloseBuyPositions(symbol); //-- if(mc.xos[x]==0 && mc.xtto<mc.ALO) mc.OpenSell(symbol); else if(mc.xtto>=mc.ALO) { //-- mc.Do_Alerts(symbol,"Maximum amount of open positions and active pending orders has reached"+ "\n the limit = "+string(mc.ALO)+" Orders "); //-- mc.CheckOpenPMx(symbol); //-- if(mc.xob[x]>0 && mc.profitb[x]<-1.02 && mc.xos[x]==0) {mc.CloseBuyPositions(symbol); mc.OpenSell(symbol);} else if(SaveOnRev==Yes) mc.CloseAllProfit(); } } } //-- mc.CheckOpenPMx(symbol); //-- if(mc.xtto>0) { //-- if(SaveOnRev==Yes) //-- Close Trade and Save profit due to weak signal (Yes) { mc.CheckOpenPMx(symbol); if(mc.profitb[x]>0.02 && mc.xob[x]>0 && mc.GetCloseInWeakSignal(symbol,mc.Buy)==mc.Sell) { mc.CloseBuyPositions(symbol); mc.Do_Alerts(symbol,"Close BUY order "+symbol+" to save profit due to weak signal."); } if(mc.profits[x]>0.02 && mc.xos[x]>0 && mc.GetCloseInWeakSignal(symbol,mc.Sell)==mc.Buy) { mc.CloseSellPositions(symbol); mc.Do_Alerts(symbol,"Close SELL order "+symbol+" to save profit due to weak signal."); } } //-- if(TrailingSLTP==Yes) //-- Use Trailing SL/TP (Yes) { if(autotrl==Yes) mc.ModifySLTP(symbol,1); //-- If Use Automatic Trailing (Yes) if(autotrl==No) mc.ModifySLTP(symbol,0); //-- Use Automatic Trailing (No) } } //-- mc.CheckClose(symbol); } //-- mc.psec=mc.ccur; } //-- return; //--- } //-end ExpertActionTrade()
3.開いたポジションと閉じたポジションの売買シグナルを得る方法
指標シグナルを取得するには、関数GetOpenPosition(symbol)を呼び出してポジションの取引シグナルを取得する必要があります。
int MCEA::GetOpenPosition(const string symbol) // Signal Open Position { //--- int ret=0; int rise=1, down=-1; //-- int dirmov=DirectionMove(symbol); int parsOp=GetPSARSignalMTF(symbol); //-- if(parsOp==rise && dirmov==rise) ret=rise; if(parsOp==down && dirmov==down) ret=down; //-- return(ret); //--- } //-end GetOpenPosition()
GetOpenPosition()関数は2つのシグナル関数を呼び出し、変数OpOr[]に格納します。
1.DirectionMove(symbol); //-- EA期間にローソク足バー上で価格が動くかどうかを確認する関数
2.GetPSARSignalMTF(symbol); //--要求された時間枠のパラボリックiSAR計算式を計算する関数
int MCEA::GetPSARSignalMTF(string symbol) // iSAR MTF signal calculation { //--- int mv=0; int rise=1, down=-1; //-- int sarup=0, sardw=0; //-- for(int x=0; x<TFArrays; x++) // The TFArrays variable has a value of 5 which is taken from the number of time frames from TF_M1 to TF_H1. { if(PARSARMTF(symbol,TFSAR[x])>0) sarup++; if(PARSARMTF(symbol,TFSAR[x])<0) sardw++; } //-- if(sarup==TFArrays) mv=rise; if(sardw==TFArrays) mv=down; //-- return(mv); //--- } //- end GetPSARSignalMTF()
GetPSARSignalMTF()関数は、要求された時間枠に従ってiSARシグナルを計算するPARSARMTF()関数を呼び出します。
ご覧のとおり、PARSARMTF()関数内で2つの関数を使用して呼び出します。
1. int xx= PairsIdxArray(symbol)
2. int tx=TFIndexArray(mtf).
pairsIdxArray()関数は、要求された銘柄の名前を取得するために使用され、TFIndexArray()関数は、要求された時間枠の時間枠配列シーケンスを取得するために使用されます。
次に、適切な指標ハンドルが呼び出され、要求された時間枠からiSAR指標のバッファ値が取得されます。
int MCEA::PARSARMTF(const string symbol,ENUM_TIMEFRAMES mtf) // formula Parabolic iSAR on the requested Timeframe { //--- int ret=0; int rise=1, down=-1; //-- int br=2; //-- double PSAR[]; ArrayResize(PSAR,br,br); ArraySetAsSeries(PSAR,true); int xx=PairsIdxArray(symbol); int tx=TFIndexArray(mtf); CopyBuffer(hPSAR[xx][tx],0,0,br,PSAR); //-- double OPN0=iOpen(symbol,TFSAR[tx],0); double HIG0=iHigh(symbol,TFSAR[tx],0); double LOW0=iLow(symbol,TFSAR[tx],0); double CLS0=iClose(symbol,TFSAR[tx],0); //-- if(PSAR[0]<LOW0 && CLS0>OPN0) ret=rise; if(PSAR[0]>HIG0 && CLS0<OPN0) ret=down; //-- return(ret); //--- } //-end PARSARMTF()
int MCEA::PairsIdxArray(const string symbol) { //--- int pidx=0; //-- for(int x=0; x<arrsymbx; x++) { if(DIRI[x]==symbol) { pidx=x; break; } } //-- return(pidx); //--- } //-end PairsIdxArray()
int MCEA::TFIndexArray(ENUM_TIMEFRAMES TF) { //--- int res=-1; //-- for(int x=0; x<TFArrays; x++) { if(TF==TFSAR[x]) { res=x; break; } } //-- return(res); //--- } //-end TFIndexArray()
//+------------------------------------------------------------------+ //| ChartEvent function | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { //--- //--- handling CHARTEVENT_CLICK event ("Clicking the chart") ResetLastError(); //-- ENUM_TIMEFRAMES CCS=mc.TFt; //-- if(id==CHARTEVENT_OBJECT_CLICK) { int lensymbol=StringLen(Symbol()); int lensparam=StringLen(sparam); //-- //--- if "Set SL All Orders" button is click if(sparam=="Set SL/TP All Orders") { mc.SetSLTPOrders(); Alert("-- "+mc.expname+" -- ",Symbol()," -- Set SL/TP All Orders"); //--- unpress the button ObjectSetInteger(0,"Set SL/TP All Orders",OBJPROP_STATE,false); ObjectSetInteger(0,"Set SL/TP All Orders",OBJPROP_ZORDER,0); CreateManualPanel(); } //--- if "Close All Order" button is click if(sparam=="Close All Order") { mc.CloseAllOrders(); Alert("-- "+mc.expname+" -- ",Symbol()," -- Close All Orders"); //--- unpress the button ObjectSetInteger(0,"Close All Order",OBJPROP_STATE,false); ObjectSetInteger(0,"Close All Order",OBJPROP_ZORDER,0); CreateManualPanel(); } //--- if "Close All Profit" button is click if(sparam=="Close All Profit") { mc.ManualCloseAllProfit(); Alert("-- "+mc.expname+" -- ",Symbol()," -- Close All Profit"); //--- unpress the button ObjectSetInteger(0,"Close All Profit",OBJPROP_STATE,false); ObjectSetInteger(0,"Close All Profit",OBJPROP_ZORDER,0); CreateManualPanel(); } //--- if "X" button is click if(sparam=="X") { ObjectsDeleteAll(0,0,OBJ_BUTTON); ObjectsDeleteAll(0,0,OBJ_LABEL); ObjectsDeleteAll(0,0,OBJ_RECTANGLE_LABEL); //--- unpress the button ObjectSetInteger(0,"X",OBJPROP_STATE,false); ObjectSetInteger(0,"X",OBJPROP_ZORDER,0); //-- DeleteButtonX(); mc.PanelExtra=false; DisplayManualButton(); } //--- if "M" button is click if(sparam=="M") { //--- unpress the button ObjectSetInteger(0,"M",OBJPROP_STATE,false); ObjectSetInteger(0,"M",OBJPROP_ZORDER,0); mc.PanelExtra=true; CreateManualPanel(); } //--- if "C" button is click if(sparam=="C") { //--- unpress the button ObjectSetInteger(0,"C",OBJPROP_STATE,false); ObjectSetInteger(0,"C",OBJPROP_ZORDER,0); mc.PanelExtra=true; CreateSymbolPanel(); } //--- if "R" button is click if(sparam=="R") { Alert("-- "+mc.expname+" -- ",Symbol()," -- expert advisor will be Remove from the chart."); ExpertRemove(); //--- unpress the button ObjectSetInteger(0,"R",OBJPROP_STATE,false); ObjectSetInteger(0,"R",OBJPROP_ZORDER,0); if(!ChartSetSymbolPeriod(0,Symbol(),Period())) ChartSetSymbolPeriod(0,Symbol(),Period()); DeletePanelButton(); ChartRedraw(0); } //--- if Symbol button is click if(lensparam==lensymbol) { int sx=mc.PairsIdxArray(sparam); ChangeChartSymbol(mc.AS30[sx],CCS); mc.PanelExtra=false; } //-- } //-- return; //--- } //-end OnChartEvent()
ワンクリックでチャート銘柄を変更するには、銘柄名のいずれかをクリックすると、OnChartEvent()が関数ChangeChartSymbol()として呼び出されます。
void ChangeChartSymbol(string c_symbol,ENUM_TIMEFRAMES cstf) { //--- //--- unpress the button ObjectSetInteger(0,c_symbol,OBJPROP_STATE,false); ObjectSetInteger(0,c_symbol,OBJPROP_ZORDER,0); ObjectsDeleteAll(0,0,OBJ_BUTTON); ObjectsDeleteAll(0,0,OBJ_LABEL); ObjectsDeleteAll(0,0,OBJ_RECTANGLE_LABEL); //-- ChartSetSymbolPeriod(0,c_symbol,cstf); //-- ChartRedraw(0); //-- return; //--- } //-end ChangeChartSymbol()
EAプロパティの[Display Trading Info on Chart]オプションで[Yes]を選択した場合、TradeInfo()関数を呼び出すことによって、EAが配置されているチャートに取引情報が表示されます。
void MCEA::TradeInfo(void) // function: write comments on the chart { //---- Pips(Symbol()); double spread=SymbolInfoInteger(Symbol(),SYMBOL_SPREAD)/xpip; //-- string comm=""; TodayOrders(); //-- comm="\n :: Server Date Time : "+string(ThisTime(year))+"."+string(ThisTime(mon))+"."+string(ThisTime(day))+ " "+TimeToString(TimeCurrent(),TIME_SECONDS)+ "\n ------------------------------------------------------------"+ "\n :: Broker : "+ TerminalInfoString(TERMINAL_COMPANY)+ "\n :: Expert Name : "+ expname+ "\n :: Acc. Name : "+ mc_account.Name()+ "\n :: Acc. Number : "+ (string)mc_account.Login()+ "\n :: Acc. TradeMode : "+ AccountMode()+ "\n :: Acc. Leverage : 1 : "+ (string)mc_account.Leverage()+ "\n :: Acc. Equity : "+ DoubleToString(mc_account.Equity(),2)+ "\n :: Margin Mode : "+ (string)mc_account.MarginModeDescription()+ "\n :: Magic Number : "+ string(magicEA)+ "\n :: Trade on TF : "+ EnumToString(TFt)+ "\n :: Today Trading : "+ TradingDay()+" : "+hariini+ "\n ------------------------------------------------------------"+ "\n :: Trading Pairs : "+pairs+ "\n :: BUY Market : "+string(oBm)+ "\n :: SELL Market : "+string(oSm)+ "\n :: Total Order : "+string(oBm+oSm)+ "\n :: Order Profit : "+DoubleToString(floatprofit,2)+ "\n :: Fixed Profit : "+DoubleToString(fixclprofit,2)+ "\n :: Float Money : "+DoubleToString(floatprofit,2)+ "\n :: Nett Profit : "+DoubleToString(floatprofit+fixclprofit,2); //--- Comment(comm); ChartRedraw(0); return; //---- } //-end TradeInfo()
多通貨EA「FXSAR_MTF_MCEA」のインターフェイスは次の図のようになります。
ご覧のとおり、EAの名前「FXSAR_MTF_MCEA」の下にボタン[M]、[C]、[R]があります。
[M]または[C]ボタンをクリックすると、以下に示すように手動クリックボタンパネルが表示されます。
[M]ボタンをクリックすると、手動クリックボタンパネルが表示され、注文を管理できます。
1.Set SL/TP All Orders
2.Close All Orders
3.Close All Profits
[C]ボタンをクリックすると、30個の銘柄名またはペアのパネルボタンが表示され、いずれかのペア名または銘柄名をクリックできます。ペア名または銘柄のいずれかがクリックされると、チャート銘柄は即座にクリックされた名前の銘柄に置き換わります。
[R]ボタンをクリックすると、多通貨EA「FXSAR_MTF_MCEA」がチャートから削除されます。
ストラレジーテスター
知られているように、MetaTrader 5ターミナルのストラテジーテスターは、ストラテジーのテスト、複数の銘柄の取引、または利用可能なすべての銘柄と利用可能なすべての時間枠の自動取引のテストをサポートしており、これを可能にします。
したがって、この機会に、MetaTrader 5ストラテジーテスタープラットフォームで多時間枠および多通貨EAとしてFXSAR_MTF_MCEAをテストします。
結論
MQL5を使用して多通貨および多時間枠のEAを作成する場合の結論は次のとおりです。
- MQL5で多通貨EAを作成するのは非常に簡単で、単一通貨のEAと大差ないことがわかりました。ただし、特に複数の時間枠を持つ複数通貨EAの場合、単一の時間枠の場合よりも少し複雑になります。
- 多通貨EAを作成すると、トレーダーは取引のために多くのチャート銘柄を開く必要がないため、トレーダーの効率と有効性が向上します。
- 適切な取引戦略を適用し、より優れた指標シグナルを計算することで、単一通貨EAを使用する場合と比較して、利益を得る確率が高まります。あるペアで発生した損失は、他のペアの利益でカバーされるからです。
- このFXSAR_MTF_MCEA多通貨EAは、アイデアを学び発展させるための単なる例です。
- ストラテジーテスターのテスト結果はまだ良くありません。したがって、より正確なシグナル計算を備えたより良い戦略が実装され、より良い時間枠が追加されれば、現在の戦略よりも良い結果が得られると思います。
注:
組み込みのMQL5標準指標シグナルに基づいてシンプルな複数通貨EAを作成するアイデアをお持ちの方は、コメントでご提案ください。
この記事とMQL5多通貨EAプログラムが、トレーダーの皆さんの学習とアイデアの開発に役立つことを願っています。ご精読ありがとうございました。
MetaQuotes Ltdにより英語から翻訳されました。
元の記事: https://www.mql5.com/en/articles/13470
![ニューラルネットワークが簡単に(第54回):ランダムエンコーダを使った効率的な研究(RE3)](https://c.mql5.com/2/57/random_encoder_for_efficient_exploration_054_avatar.png)
![GUI:MQLで独自のグラフィックライブラリを作成するためのヒントとコツ](https://c.mql5.com/2/58/gui_tips_and_tricks_avatar.png)
![ニューラルネットワークが簡単に(第55回):対照的内発制御(Contrastive intrinsic control、CIC)](https://c.mql5.com/2/57/cic-055-avatar.png)
![MQL5 - MetaTrader 5クライアントターミナルにビルトインされたトレードストラテジーの言語](https://c.mql5.com/i/registerlandings/logo-2.png)
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索