Lite_EXPERT2.mqhファイル - EAの最適化の実践例
概論
私の前回の記事『ファイルLite_EXPERT2.mqh―エキスパートアドバイザー開発者の為の関数キット』で、私は読者にLite_EXPERT2.mqhファイルの関数をご紹介しました。この記事では私はこれらの関数をベースにしたEAの具体的な実装例を提供したいと思います。私が考える取引関数は、
OpenBuyOrder1_() OpenSellOrder1_() OpenBuyOrder2_() OpenSellOrder2_() OpenBuyLimitOrder1_() OpenBuyStopOrder1_() OpenSellLimitOrder1_() OpenSellStopOrder1_() Make_BuyTrailingStop_() Make_SellTrailingStop_()
Lite_EXPERT1.mqhファイルの分析関数との動作に関わる重大な違いはありません。そこに発生したいくつかの余分な外部変数の初期化は、いかなる混乱も招きません。(参照:Exp_0_1.mq4 и Exp_0.mq4, Exp_1.mq4 и EXP_1_1.mq4)その為、もう一度それらを勉強する必要はありません。よって、私はすぐに価格チャートレベルの絶対値の指値注文の為に、外部変数としての取引関数に基づいて使用する例に移りたいと思います。
ddOpenBuyOrder1_() dOpenSellOrder1_() dOpenBuyOrder2_() dOpenSellOrder2_() dOpenBuyLimitOrder1_() dOpenBuyStopOrder1_() dOpenSellLimitOrder1_() dOpenSellStopOrder1_() dModifyOpenBuyOrder_() dModifyOpenSellOrder_() dModifyOpenBuyOrderS() dModifyOpenSellOrderS() dMake_BuyTrailingStop_() dMake_SellTrailingStop_()
この記事の下で検証される取引戦略は、Average True Rangeインディケータをベースにし、私はこのことからこの記事の記述を始めます。
テクニカル取引システムにおけるAverage True Rangeインディケータの使用
Average True Range インディケータ(以降、ATR、またはアベレージ・トゥルー・レンジ)はウェルス・ワイルダーによって開発され、初めに彼の著書『テクニカル取引システムにおける新しいコンセプト』の中に出現しました。その後、この指標はとても人気になり、今でも多くのテクニカル分析のプログラムパケットに含まれています。ATRインディケータ自身は現在のトレンドの方向を示していませんが、ボラティリティまたは調査している市場の能動性をチャートとして反映します。
機械的取引システムでのこのインディケータの使用には2つの方法があります。
1. 取引システムシグナルのフィルタリングはトレンドと非トレンドの市場状態を認識する為のものです。
この時、トレンドの方向と入力シグナルは他のインディケータから受取りますが、ATRインディケータは入力の追加条件を与えるだけです。このような追加条件は、インディケータ自身によるインディケータの平均値テストとなりえます。ATRの平均値を取得する為にはATRからのシグナル平均を利用すると便利です。
2. 適応指値注文
このインディケータの絶対値は、強い価格変動を起こす可能性の高い領域のバーの開始値からの距離を明確にします。したがって、これらの条件は、オープンポジションやストップロスの為に指値注文を持つのにとても便利です。この場合、私達はATRインディケータを使い、実際の市場で、ずっと前の戦争に執拗に準備をする古き良き将軍にどこか強く似ている固定された場ではなく、現在の市場のボラティリティ下でそれぞれの取引において並べられる適応価格からの距離で注文をすることができます。それは時として、刻々と変わっていく実際の市場での取引システムの働きのより興味深い結果へと導きます。非常に似た方法では、バーが変化するたびに、ATR距離の価格にトレーリングストップを当てることができます。
これで、Lite_EXPERT2.mqhファイルを使ったEAの構成に着手することができます。取引上での柔軟性を加えるために、Lite_EXPERT1.mqhファイルをベースにしたEAの近代化から始めるといいです。
移動方向変動の市場からの入力と出力シグナルとしての取引システムの利用
このようなシステムについては私はすでに最も単純な取引システムに向けた自分の記事『人気取引システムをベースにしたEAと取引動作最適化の錬金術』にて詳しく検証しましたが、ここでそれを少し複雑にする時がきました。Lite_EXPERT2.mqhファイルの関数でのこの取引システムの殆ど完全な類似物が、Exp_1_1.mq4 (оригинал Exp_1.mq4)のEAで開発されています。全ての課題は、ATR単位で計算しなおされる固定ストップロスとテイクプロフィットの変換をすることと、バーの推移ごとに一度移動する類似のトレーリングストップを追加することにあります。これは2つのステップで行うのが良いでしょう。始めにストップロスとテイクプロフィットを変換し(Exp_17_A.mq4のEA)、エラーの有無と選択したストラテジーの適合のコード検査後にトレーリングストップを追加します(Exp_17.mq4のEA)。私は記事のテキストにコードの追加変更の詳細をより明らかにした最終案を引用します。
//+X================================================================X+ //| Exp_17.mq4 | //| Copyright © 2009, Nikolay Kositsin | //| Khabarovsk, farria@mail.redcom.ru | //+X================================================================X+ #property copyright "Copyright © 2009, Nikolay Kositsin" #property link "farria@mail.redcom.ru" //+---------------------------------------------+ //| 買い取引の為のEAの入力パラメータ | //+---------------------------------------------+ extern bool Test_Up = true;//取引計算方針フィルター extern int Timeframe_Up = 240; extern double Money_Management_Up = 0.1; extern int Length_Up = 4; // 補正深度 extern int Phase_Up = 100; // 範囲内で変わるパラメータ //-100 ... +100は、移行プロセスの質に影響します extern int IPC_Up = 0;/* 計算が行われる価格の選択 インディケータ(0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 14-Heiken Ashi Close.) */ extern int ATR_Period_Up = 14; // True Rangeの平均期間 extern int LevMinimum_Up = 40; // 項目内の最小値 // その数値よりも低い指値注文は入りません extern int STOPLOSS_Up = 100; // ATR%におけるストップロス extern int TAKEPROFIT_Up = 200; // ATR%におけるテイクプロフィット extern int TRAILINGSTOP_Up = 100; // ATR%におけるトレーリングストップ extern bool ClosePos_Up = true; // 強制ポジションクローズの許可 //+---------------------------------------------+ //| 売り取引の為のEAの入力パラメータ | //+---------------------------------------------+ extern bool Test_Dn = true;//取引計算方針フィルター extern int Timeframe_Dn = 240; extern double Money_Management_Dn = 0.1; extern int Length_Dn = 4; // 補正深度 extern int Phase_Dn = 100; // 範囲内で変わるパラメータ // -100 ... +100は、移行プロセスの質に影響します extern int IPC_Dn = 0;/* 計算が行われる価格の選択 インディケータ(0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 14-Heiken Ashi Close.) */ extern int ATR_Period_Dn = 14; // True Rangeの平均期間 extern int LevMinimum_Dn = 40; // 項目内の最小値 // その数値よりも低い指値注文は入りません extern int STOPLOSS_Dn = 100; // ATR%におけるストップロス extern int TAKEPROFIT_Dn = 200; // ATR%におけるテイクプロフィット extern int TRAILINGSTOP_Dn = 100; // ATR%におけるトレーリングストップ extern bool ClosePos_Dn = true; // 強制ポジションクローズの許可 //+---------------------------------------------+ //---- 最少計算バーの為の全変数の宣言 int MinBar_Up, MinBar_Dn; //---- 秒ごとのチャート期間の為の全変数の宣言 int Period_Up, Period_Dn; //---- 指値注文の為の変動箇所を伴う変数の宣言 double _STOPLOSS_Up, _TAKEPROFIT_Up, _LevMinimum_Up, _TRAILINGSTOP_Up; double _STOPLOSS_Dn, _TAKEPROFIT_Dn, _LevMinimum_Dn, _TRAILINGSTOP_Dn; //+X================================================================X+ //| Custom Expert functions | //+X================================================================X+ #include <Lite_EXPERT2.mqh> //+X================================================================X+ //| Custom Expert initialization function | //+X================================================================X+ int init() { //---- Timeframe_Up変数値の正確性の検査 TimeframeCheck("Timeframe_Up", Timeframe_Up); //---- Timeframe_Dn変数値の正確性の検査 TimeframeCheck("Timeframe_Dn", Timeframe_Dn); //---- 変数の初期化 MinBar_Up = 4 + 39 + 30;// シグナルの為の4つのバー //入力 + FATLフィルターの長さ + JMAフィルターの長さ MinBar_Up = MathMax(MinBar_Up, ATR_Period_Up + 1); MinBar_Dn = 4 + 39 + 30;// シグナルの為の4つのバー //入力 + FATLフィルターの長さ + JMAフィルターの長さ MinBar_Dn = MathMax(MinBar_Dn, ATR_Period_Dn + 1); //---- Period_Up = Timeframe_Up * 60; // 秒ごとのロングポジションの為のチャート期間 Period_Dn = Timeframe_Dn * 60; // 秒ごとのショートポジションの為のチャート期間 //---- 分数への%の換算 _STOPLOSS_Up = STOPLOSS_Up / 100.0; _TAKEPROFIT_Up = TAKEPROFIT_Up / 100.0; _TRAILINGSTOP_Up = TRAILINGSTOP_Up / 100.0; //---- 分数への%の換算 _STOPLOSS_Dn = STOPLOSS_Dn / 100.0; _TAKEPROFIT_Dn = TAKEPROFIT_Dn / 100.0; _TRAILINGSTOP_Dn = TRAILINGSTOP_Dn / 100.0; //---- 点の最小値の最少価格距離への換算 _LevMinimum_Up = LevMinimum_Up * Point; _LevMinimum_Dn = LevMinimum_Dn * Point; //---- 初期化完了 return(0); } //+X================================================================X+ //| expert deinitialization function | //+X================================================================X+ int deinit() { //----+ //----+ グローバル変数の除去 //テストと最適化後 TimeLevelGlobalVariableDel(Symbol(), 1); TimeLevelGlobalVariableDel(Symbol(), 2); //---- EAの初期化解除完了 return(0); //----+ } //+X================================================================X+ //| Custom Expert iteration function | //+X================================================================X+ int start() { //----+ //----+ ローカル変数宣言 int bar; double Mov[3], dMov12, dMov23, ATR, Level, open; //----+ 静的変数宣言 static datetime TradeTimeLevel_Up, TradeTimeLevel_Dn; //---- static bool BUY_Sign, BUY_Stop, SELL_Sign, SELL_Stop; static bool TrailSignal_Up, TrailSignal_Dn; //---- static double dStopLoss_Up, dTakeProfit_Up, dTrailingStop_Up; static double dStopLoss_Dn, dTakeProfit_Dn, dTrailingStop_Dn; //+---------------------------+ //| ロングポジション用コード | //+---------------------------+ if (Test_Up) if (MinBarCheck(Symbol(), Timeframe_Up, MinBar_Up)) { if (IsNewBar(0, Symbol(), Timeframe_Up)) { //----+ 取引シグナルのゼロ化 BUY_Sign = false; BUY_Stop = false; //---- 禁止の時間域の取得 // 次の取引操作の TradeTimeLevel_Up = iTime(NULL, Timeframe_Up, 0); if (TradeTimeLevel_Up == 0) return(-1); TradeTimeLevel_Up += Period_Up; //----+ インディケータ値の演算とそれらのバッファへのブート for(bar = 1; bar <= 3; bar++) Mov[bar - 1]= iCustom(NULL, Timeframe_Up, "JFatl", Length_Up, Phase_Up, 0, IPC_Up, 0, bar); //----+ 取引の為のシグナルの決定 dMov12 = Mov[0] - Mov[1]; dMov23 = Mov[1] - Mov[2]; //---- ポジションオープンの為のシグナルの取得 if (dMov23 < 0) if (dMov12 > 0) BUY_Sign = true; //---- ポジションクローズの為のシグナルの取得 if (dMov12 < 0) if (ClosePos_Up) BUY_Stop = true; //----+ ロングポジションの為の指値注文の演算 // 取引シグナルがある時のみ注文の算定をします if (BUY_Sign) { //---- ATR初期値の取得 ATR = iATR(NULL, Timeframe_Up, ATR_Period_Up, 1); //---- 現在価格の取得 open = iOpen(Symbol(), Timeframe_Up, 0); //---- ストップロスまでの距離の演算 Level = ATR * _STOPLOSS_Up; //---- ストップロスまでの距離の最少値の検算 if (Level < _LevMinimum_Up) Level = _LevMinimum_Up; //---- ストップロスの絶対値の算定 dStopLoss_Up = open - Level; //---- テイクプロフィットまでの距離の演算 Level = ATR * _TAKEPROFIT_Up; //---- テイクプロフィットまでの最小値の検算 if (Level < _LevMinimum_Up) Level = _LevMinimum_Up; //---- テイクプロフィットの絶対値の算定 dTakeProfit_Up = open + Level; //---- 取引傾向を計算に入れた // 指値注文の値の補正 dGhartVelueCorrect(OP_BUY, dStopLoss_Up); dGhartVelueCorrect(OP_BUY, dTakeProfit_Up); } //----+ ロングポジションの為のトレーリングストップの演算 dTrailingStop_Up = 0; TrailSignal_Up = false; //---- if (TRAILINGSTOP_Up > 0) // 必要不可欠なポジションがある場合のみトレーリングストップの算定をします if (OrderSelect_(Symbol(), OP_BUY, 1, MODE_TRADES)) // オープンポジションがゼロ線上でない場合、トレーリングストップを動かします if (iBarShift(NULL, Timeframe_Up, OrderOpenTime(), false) > 0) { TrailSignal_Up = true; //---- ATR初期値の取得 ATR = iATR(NULL, Timeframe_Up, ATR_Period_Up, 1); //---- 現在価格の取得 open = iOpen(Symbol(), Timeframe_Up, 0); //---- ストップロスまでの距離の演算 Level = ATR * _TRAILINGSTOP_Up; //---- ストップロスまでの距離の最少値の検算 if (Level < _LevMinimum_Up) Level = _LevMinimum_Up; //---- トレーリングストップの絶対値の取得 dTrailingStop_Up = open - Level; //---- 取引傾向を計算に入れた // トレーリングストップの絶対値の補正 // (ポジション変更関数の為のcmd変数値は逆になる) dGhartVelueCorrect(OP_SELL, dTrailingStop_Up); } } //----+ 取引の実行 if (!dOpenBuyOrder1_(BUY_Sign, 1, TradeTimeLevel_Up, Money_Management_Up, 5, dStopLoss_Up, dTakeProfit_Up)) return(-1); //---- if (!CloseBuyOrder1_(BUY_Stop, 1)) return(-1); //---- if (!dMake_BuyTrailingStop_(TrailSignal_Up, 1, TradeTimeLevel_Up, dTrailingStop_Up)) return(-1); } //+---------------------------+ //| ショートポジション用コード | //+---------------------------+ if (Test_Dn) if (MinBarCheck(Symbol(), Timeframe_Dn, MinBar_Dn)) { if (IsNewBar(1, Symbol(), Timeframe_Dn)) { //----+ 取引シグナルのゼロ化 SELL_Sign = false; SELL_Stop = false; //---- 禁止の時間域の取得 // 次の取引操作の TradeTimeLevel_Dn = iTime(NULL, Timeframe_Dn, 0); if (TradeTimeLevel_Dn == 0) return(-1); TradeTimeLevel_Dn += Period_Dn; //----+ インディケータ値の演算とそれらのバッファへのブート for(bar = 1; bar <= 3; bar++) Mov[bar - 1]= iCustom(NULL, Timeframe_Dn, "JFatl", Length_Dn, Phase_Dn, 0, IPC_Dn, 0, bar); //----+ 取引の為のシグナルの決定 dMov12 = Mov[0] - Mov[1]; dMov23 = Mov[1] - Mov[2]; //---- ポジションオープンの為のシグナルの取得 if (dMov23 > 0) if (dMov12 < 0) SELL_Sign = true; //---- ポジションクローズの為のシグナルの取得 if (dMov12 > 0) if (ClosePos_Dn) SELL_Stop = true; //----+ ショートポジションの為の指値注文の演算 // 取引シグナルがある時のみ注文の算定をします if (SELL_Sign) { //---- ATR初期値の取得 ATR = iATR(NULL, Timeframe_Dn, ATR_Period_Dn, 1); //---- 現在価格の取得 open = iOpen(Symbol(), Timeframe_Dn, 0); //---- ストップロスまでの距離の演算 Level = ATR * _STOPLOSS_Dn; //---- ストップロスまでの距離の最少値の検算 if (Level < _LevMinimum_Dn) Level = _LevMinimum_Dn; //---- ストップロスの絶対値の算定 dStopLoss_Dn = open + Level; //---- テイクプロフィットまでの距離の演算 Level = ATR * _TAKEPROFIT_Dn; //---- テイクプロフィットまでの最小値の検算 if (Level < _LevMinimum_Dn) Level = _LevMinimum_Dn; //---- テイクプロフィットの絶対値の算定 dTakeProfit_Dn = open - Level; //---- 取引傾向を計算に入れた // 指値注文の値の補正 dGhartVelueCorrect(OP_SELL, dStopLoss_Dn); dGhartVelueCorrect(OP_SELL, dTakeProfit_Dn); } //----+ ショートポジションの為のトレーリングストップの演算 dTrailingStop_Dn = 0; TrailSignal_Dn = false; //---- if (TRAILINGSTOP_Dn > 0) // 必要不可欠なポジションがある場合のみトレーリングストップの算定をします if (OrderSelect_(Symbol(), OP_SELL, 2, MODE_TRADES)) // オープンポジションがゼロ線上でない場合、トレーリングストップを動かします if (iBarShift(NULL, Timeframe_Dn, OrderOpenTime(), false) > 0) { TrailSignal_Dn = true; //---- ATR初期値の取得 ATR = iATR(NULL, Timeframe_Dn, ATR_Period_Dn, 1); //---- 現在価格の取得 open = iOpen(Symbol(), Timeframe_Dn, 0); //---- ストップロスまでの距離の演算 Level = ATR * _TRAILINGSTOP_Dn; //---- ストップロスまでの距離の最少値の検算 if (Level < _LevMinimum_Dn) Level = _LevMinimum_Dn; //---- トレーリングストップの絶対値の取得 dTrailingStop_Dn = open + Level; //---- 取引傾向を計算に入れた // トレーリングストップの絶対値の補正 // (ポジション変更関数の為のcmd変数値は逆になる) dGhartVelueCorrect(OP_BUY, dTrailingStop_Dn); } } //----+ 取引の実行 if (!dOpenSellOrder1_(SELL_Sign, 2, TradeTimeLevel_Dn, Money_Management_Dn, 5, dStopLoss_Dn, dTakeProfit_Dn)) return(-1); //---- if (!CloseSellOrder1_(SELL_Stop, 2)) return(-1); //---- if (!dMake_SellTrailingStop_(TrailSignal_Dn, 2, TradeTimeLevel_Dn, dTrailingStop_Dn)) return(-1); } return(0); //----+ } //+X----------------------+ <<< The End >>> +-----------------------X+
さて、EAの外部変数のユニットにいくつかの新しい変数が現れました。ATR_Period_UpとATR_Period_Dnで、これらによって、指値注文の算定に使用するATRインディケータの値を変更できます。これからストップロスやテイクプロフィット、トレーリングストップの為の外部変数値に、いくつかの他の論理的意味が入れられます。以前はこれは注文から現在価格までの相対的距離でした。ここでは、これは最初のバーのATRインディケータ値の%を表します。つまり、注文の演算の為にATRインディケータ値の%をとり、ゼロバー開始価格の値に追加されます。このようにして、変動点を持つ数字の%の総計は、これらの演算が一度だけでできるEAのinit() のブロックを使用することが最も良く、計算された値はグローバルレベルで宣言される変数に保存されます。
init()のブロックでは、新しいATRインディケータがある為、LevMinimum_Upと LevMinimum_Dn変数の初期化の為に式が変更されました。EAのstart()のブロックでは、ターミナルのティック間の値を保存することが必要な為、静的として宣言された新しい変数が現れました。指値注文とトレーリングストップの演算の為のコードは、取引用のシグナル取得の為にブロック内部の小さなモジュールとして構成されました。取引の実行の為に、Margin_Mode変数の初期化に変動するストップロスの際により合理的な5が使用された他の変数が使用されました。
IndicatorCounted_()とReSetAsIndexBuffer()の関数が利用できるかどうかのデモンストレーションの為に、このEAの中でユーザ・インディケータのJFatl.mq4が、EAのコード内にあるJFATL()関数に変換されました。
bool JFATL(int Number, string symbol, int timeframe, int Length, int Phase, int IPC, double& Buffer[])
関数はインディケータの入力パラメータとBuffer[]配列を採用します。算定が上手く実行された場合、関数はtrueを返し、上手く行かなかった場合はfalseを返します。引用の配列はJFATLインディケータの値によって埋められたインディケータバッファのアナログへ変わります。関数では、JJMASeries()がゼロバー上で計算を行わないJJMASeries1()に置き換えられました。同様に関数PriceSeries()がiPriceSeries()に置き換えられました。インディケータ初期化ブロックは、『ゼロ初期化』ブロックへ配置されました。このEAでは、この関数以外で関数JJMASeries1()はどこにも使用されておらず、その為、変数Numberの値は計算し直されて、関数JJMASeries1()へ直に送られます。関数IndicatorCounted_()についても同様です。
こういったインディケータの関数への置き換えについてはすでに私の記事のこのテーマ 1, 2, 3に書いています。この置き換えを伴うEAはファイルExp_17_.mq4で紹介されています。JFatl.mq4のインディケータに使用された補正のJMAアルゴリズムは十分大量のリソースを消費すること、また以前のものと比較した場合、こういったインディケータの置き換えは、とても重要なEAの最適化速度の増大をインディケータ関数によって提供するという事実に触れておく必要があります。そして最後に、特に面倒臭がりな方の為に、エキスパートコードの中に全ての必要不可欠な関数があり、コンパイルや自身の動作の為にいかなる追加のファイルもインディケータも必要としないこのEA(Exp_17R.mq4)が作られました。このEAの3つのアナログ全てが完全に同一に動いています!果たして最終EAでは、Heiken Ashi#.mq4インディケータへのアピールがないことで、IPC_UpとIPC_Dnの変数値がいくらか小さいサイズ(0-10)に変わるのだろうか。
時々、フォーラムではMQL4のプログラムの熟練者からでさえ、このようなインディケータ関数を書くのは、ズボンを頭から被るようなものだという喚声が響く。私の場合は、例えば、この関数を十分に分かり易いコードで記入するプロセスにかかる時間は全部で15分です。つまり、もし後にこのズボンで、またこうした装いで、最適化というマラソンの道程を6倍速く走ることができるのなら、私は自分の為にこの道を選びます!
ニュースにおける取引のためのブレイクアウトシステム
この取引システムのバージョンは、閲覧用にExp_10.mq4のEAによる私の記事で紹介されています。Lite_EXPERT2.mqh関数で実行されたExp_10_1.mq4のEAのバージョンはその完全な類似物です。それは少し最初のバージョンよりも難しそうに思えますが、その代わり動作において遥かに確実で、EAやターミナル、またはOSの再起動に全く影響を受けません。このEAでは、その後にオープンポジションを閉じる必要がある時間を算定する為に、関数TradeTimeLevelCheck()が使われます。
bool TradeTimeLevelCheck (string symbol, int MagicNumber, datetime TradeTimeLevel)
この関数は、指値注文とポジションを開くために関数が入力パラメータとして受取った時間の後で、trueを返します。この関数は時間の数値自体はグローバル変数から得ます。
ここから指値注文の算定のアルゴリズムの変更が必要です。しかしこの状況では、ストップロスやテイクプロフィットだけでなく、逆指値注文も再計算する必要があります。全く何も変えずに、全て全く同じにできます。おまけに、初期のEAではトレーリングストップはそれぞれのティックで動作しますが、ミッションはそれをバーの変化ごとに置き換えるように設けられます。勿論、EA(Exp_18.mq4)の最終コードはすでに、最初のものほどそんなに簡単ではありませんが、プログラムコードにおける思考進化の論理は簡潔で分かり易いものになりました。ファイルExp_18R.mq4は、自己完結型のファイルとして実行された最終EAの完全な類似物です。
おわりに
私はプログラムのアプローチの観点からは、Lite_EXPERT2.mqhファイルのユーザ関数とLite_EXPERT1.mqhファイルを比べても、新しいものは何もないと思います。プログラムの可能性が大きくなっただけでした。これらの関数適用の本質そのものは以前のまま残りました。Lite_EXPERT1.mqhファイルの関数適応を使って注意深く開発をした人は、十分に速く簡単にLite_EXPERT2.mqhファイルの機能的可能性を使いこなすことができるでしょう。
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/1384
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索