
さまざまな移動平均タイプをテストして、それらがどの程度洞察力に富むかを確認する
はじめに
前回の記事では、最も一般的な移動平均のタイプ(単純移動平均、加重移動平均、指数移動平均)について考察しました(「さまざまな移動平均システムを設計する方法を学ぶ」)。この記事ではこのトピックを続け、単純移動平均を使用して他のタイプの移動平均線とその結果を比較します。多くのトレーダーが、好みに応じて移動平均を使い分けています。そこで、この記事では、さまざまなタイプを詳細に検討し、パフォーマンスをテストして結果を比較し、どのタイプがより優れたパフォーマンスを発揮するかを特定します。
この記事では、内蔵のMetaTrader 5ストラテジーテスターで平均値のバックテストを行うための簡単なアプリケーションを作成します。テスト結果を検討する際に注目すべき点を理解するために、私の以前の記事「MQL5ストラテジーテスターを理解し、効果的に活用する」をご覧ください。役立つ情報がたくさん含まれています。
さまざまなタイプの移動平均を検討し、そのパフォーマンスを確認するために、以下のトピックを検討します。
- 単純移動平均(SMA)システムテスト
- 適応移動平均(iAMA)
- 二重指数移動平均(iDEMA)
- 三重指数移動平均(iTEMA)
- フラクタル適応移動平均(iFrAMA)
- 単純移動平均(SMA)の結果との比較
- 結論
最高の結果が得られるよう、各移動平均の設定を最適化するよう努めますが、ここでの目的はあくまで教育であるため、ご自身でより多くのチェックとテストをおこなっていただく必要があることにご注意ください。テストして最適化し、より良い結果が得られる設定を見つけてください。これらのタイプのいずれか、あるいはすべてが読者の取引スタイルに合わないということも起こり得ますが、読者が取引を向上させるために役立つ洞察を見つけられることを願っています。一般的に、どのような理想を満たすにせよ、実際の口座で使用する前に取引戦略のパフォーマンスを測定することが重要です。
単純移動平均(SMA)システムテスト
この部分では、単純移動平均の戦略のみに基づくシンプルなシステムの結果を共有します。価格と単純移動平均線のクロスオーバーを見つけ、売買シグナルを発生させます。これらのシグナルを自動的に実行できるシステムを構築します。
以下のシグナルを利用して取引操作をおこないます。
買いシグナル
終値が単純移動平均値を上回っている。
かつ、直前の終値が直前の単純移動平均値を下回っている。
売りシグナル
終値が単純移動平均値を下回っている。
かつ、前回の終値が前回の単純移動平均値を上回っている。
単純移動平均やその他の一般的な移動平均について知りたい方は、以前の「さまざまな移動平均システムを設計する方法を学ぶ」稿をお読みになることをお勧めします。これは、移動平均システムについてよく理解し、この記事をよく理解するのに役立つと思います。
以下は、これらのシグナルに基づいて売買注文を自動的に実行できる、このタイプの取引システムを作成するための手順です。
グローバルスコープでは、プリプロセッサ#includeを使ってシグナルに基づいた注文を実行できるようにするため、Tradeインクルードファイルをソフトウェアにインクルードします。プリプロセッサについてもっと詳しく知りたい方は、「MQL5のプログラム構造について学ぶ必要があるすべて」をお読みください。
#include <Trade\Trade.mqh>
double型lotSize変数、ENUM_TIMEFRAMES型timeFrame変数、integer型MAPeriodの変数の3つのユーザー入力を作成し、デフォルト値で初期化しながら、ユーザーが希望に応じて値を変更できるようにします。
input double lotSize = 1; input ENUM_TIMEFRAMES timeFrame = PERIOD_H1; input int MAPeriod= 50;
後でOnInit()で定義するので、代入せずにsimpleMAとbarsTotalの2つの整数変数を作成します。
int simpleMA; int barsTotal;
CTradeクラスからオブジェクトとしてtradeを作成し、取引関数に簡単にアクセスできるようにします。
CTrade trade;
OnInit()で、移動平均指標のハンドルを返すiMA関数を使用してsimpleMAを定義します。パラメータは次の通りです。
- symbol:銘柄(現在の銘柄に_Symbolを使用)
- period:時間枠(ユーザー入力を使用、デフォルト値1時間)
- ma_period:移動平均期間(ユーザー入力を使用、デフォルト値50)
- ma_shift:水平方向のシフト(0を使用)
- applied_price:価格の種類(単純移動平均の計算では終値を使用)
simpleMA = iMA(_Symbol, timeFrame, MAPeriod, 0, MODE_SMA, PRICE_CLOSE);
barsTotalは、iBars関数を使ってバーの数を返します。パラメータは以下の通りです。
- symbol:銘柄(現在の銘柄に適用される_Symbolを使用)
- timeframe:時間枠(ユーザー入力を使用、デフォルト値1時間)
barsTotal=iBars(_Symbol,timeFrame);
OnTick()では、MqlRatesを使用して価格、出来高、スプレッドに関する情報を格納する価格用の配列と、単純移動平均用の配列を2つ作成します。
MqlRates priceArray[]; double mySMAArray[];
これらの2つの配列にAS_SERIESフラグを設定するには、ArraySetAsSeries関数を使用します。パラメータは以下の通りです。
- array[]:参照で配列を指定
- flag:配列のインデックス方向を指定
ArraySetAsSeries(priceArray,true); ArraySetAsSeries(mySMAArray,true);
2つのdouble変数を作成した後の売値と買値の定義
double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
CopyRates関数を使用してMqlRatesの履歴データを取得します。
- symbol_name:銘柄名
- timeframe:時間枠
- start_pos:開始位置
- count:コピーするデータの数
- rates_array[]:コピー先の配列
int Data=CopyRates(_Symbol,_Period,0,3,priceArray);
CopyBuffer関数を使用して指標バッファのデータを取得します。
- indicator_handle:指標(simpleMA)のハンドル
- buffer_num:指標のバッファ番号(0を使用)
- start_pos:現在のローソク足の開始位置(0を使用)
- count:コピーする量(3を使用)
- buffer[]:コピー先の配列(mySMAArrayを使用)
CopyBuffer(simpleMA,0,0,3,mySMAArray);
同じローソク足の最終終値と単純移動平均値を定義し、この2つの値から2つのdouble変数を作成します。
double lastClose=(priceArray[1].close); double SMAVal = NormalizeDouble(mySMAArray[1],_Digits);
同じローソク足の前回の終値と単純移動平均値を定義し、この2つの値から他の2つのdouble変数を作成します。
double prevClose=(priceArray[2].close); double prevSMAVal = NormalizeDouble(mySMAArray[2],_Digits);
作成されたbarsTotal変数と比較されるinteger型bars変数を作成します。
int bars=iBars(_Symbol,timeFrame);
barsTotalがbarsと等しいかどうかを確認して、新しいバーが作成されたかどうかを確認します。
if(barsTotal != bars)
barsTotalがbarsと等しくない場合、barsTotalをbarsの値で更新します。
barsTotal=bars;
barsTotalがbarsと等しくなく、最後の終値が同じローソク足の単純移動平均の値を下回っていると同時に最後の終値が同じローソク足の単純移動平均の値を上回っている場合、戦略の条件をチェックします。現在開いているポジションを閉じ、買いポジションを開くプログラムが必要です。
if(prevClose<prevSMAVal && lastClose>SMAVal) { trade.PositionClose(_Symbol); trade.Buy(lotSize,_Symbol,Ask,0,0,NULL); }
直近の終値が同じローソク足の単純移動平均の値を上回っており、同時に直近の終値が同じローソク足の単純移動平均の値を下回っている場合。現在開いているポジションを閉じ、売りポジションを開くプログラムが必要です。
if(prevClose>prevSMAVal && lastClose<SMAVal) { trade.PositionClose(_Symbol); trade.Sell(lotSize,_Symbol,Bid,0,0,NULL); }
コードをコンパイルしてみると、エラーも警告もなくコンパイルされていることがわかります。
以下は、1ブロックのフルコードです。
//+------------------------------------------------------------------+ //| SMA_System.mq5 | //+------------------------------------------------------------------+ #include <Trade\Trade.mqh> input double lotSize = 1; input ENUM_TIMEFRAMES timeFrame = PERIOD_H1; input int MAPeriod= 50; int simpleMA; int barsTotal; CTrade trade; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { simpleMA = iMA(_Symbol, timeFrame, MAPeriod, 0, MODE_SMA, PRICE_CLOSE); barsTotal=iBars(_Symbol,timeFrame); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { MqlRates priceArray[]; double mySMAArray[]; double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits); ArraySetAsSeries(priceArray,true); ArraySetAsSeries(mySMAArray,true); int Data=CopyRates(_Symbol,_Period,0,3,priceArray); CopyBuffer(simpleMA,0,0,3,mySMAArray); double lastClose=(priceArray[1].close); double SMAVal = NormalizeDouble(mySMAArray[1],_Digits); double prevClose=(priceArray[2].close); double prevSMAVal = NormalizeDouble(mySMAArray[2],_Digits); int bars=iBars(_Symbol,timeFrame); if(barsTotal != bars) { barsTotal=bars; if(prevClose<prevSMAVal && lastClose>SMAVal) { trade.PositionClose(_Symbol); trade.Buy(lotSize,_Symbol,Ask,0,0,NULL); } if(prevClose>prevSMAVal && lastClose<SMAVal) { trade.PositionClose(_Symbol); trade.Sell(lotSize,_Symbol,Bid,0,0,NULL); } } } //+------------------------------------------------------------------+
EAをコンパイルして、EURUSDのデータでEAを実行し、戦略のバックテストをおこないます。前述のすべての移動平均タイプと同様、テスト期間は2022年1月1日から6月30日までです。SMAの設定は以下のようになります。
- ロットサイズ:1
- 時間枠:1 時間
- MA期間:50
テストの結果
SMA指標のテスト結果は以下のようになります。
- 純利益:2700.30 (27%)
- バランスDD(相対):37.07%
- エクイティDD(相対):41.76%
- プロフィットファクター:1.10
- 予想ペイオフ:12.68
- リカバリーファクター:0.45
- シャープレシオ:0.57
適応移動平均(iAMA)
この部分では、移動平均のもう1つのタイプであるAMA (Adaptive Moving Average)について学びます。これはペリー・J・カウフマンによって開発されたもので、KAMAとも呼ばれ、その主なアイディアは値動きのノイズを減らすことです。価格の変動がどのようなものであれ、それに適応しながら価格の動きに従います。この指標は、トレンドフォロワー指標であるため、トレン ドと転換点を識別するのに使用できます。
この指標はいくつかのステップで計算されます。
ステップ1:AMA(KAMA)の計算
ステップ2:平滑化定数(SC)の計算
ステップ3:効率比(ER)の計算
AMA指標を手動で計算する方法を学びましたが、この指標はMetaTrader 5で利用可能で、既製の指標リストから選択して自動的に挿入できるので、手動で計算する必要はありません。次に、終値とAMA指標のクロスオーバーに基づいて売買注文を実行できる取引システムを作成します。この戦略では以下のシグナルを使うことにします。
買いシグナル:
終値が適応移動平均値を上回っている。
かつ、直前の終値が直前の適応移動平均値を下回っている。
売りシグナル:
終値が適応移動平均値を下回っている。
かつ、前回の終値が前回の適応移動平均値を上回っている。
以下は、このタイプの取引システムを作成するための完全なコードです。
//+------------------------------------------------------------------+ //| iAMA_System.mq5 | //+------------------------------------------------------------------+ #include <Trade\Trade.mqh> input double lotSize = 1; input ENUM_TIMEFRAMES timeFrame = PERIOD_H1; input int MAPeriod= 50; input int fastMAPeriod= 5; input int slowMAPeriod= 100; int adaptiveMA; int barsTotal; CTrade trade; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { adaptiveMA = iAMA(_Symbol, timeFrame, MAPeriod,fastMAPeriod,slowMAPeriod, 0, PRICE_CLOSE); barsTotal=iBars(_Symbol,timeFrame); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { MqlRates priceArray[]; double myAMAArray[]; double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits); ArraySetAsSeries(priceArray,true); ArraySetAsSeries(myAMAArray,true); int Data=CopyRates(_Symbol,timeFrame,0,3,priceArray); CopyBuffer(adaptiveMA,0,0,3,myAMAArray); double lastClose=(priceArray[1].close); double AMAVal = NormalizeDouble(myAMAArray[1],_Digits); double prevClose=(priceArray[2].close); double prevAMAVal = NormalizeDouble(myAMAArray[2],_Digits); int bars=iBars(_Symbol,timeFrame); if(barsTotal != bars) { barsTotal=bars; if(lastClose>AMAVal && prevClose<prevAMAVal) { trade.PositionClose(_Symbol); trade.Buy(lotSize,_Symbol,Ask,0,0,NULL); } if(lastClose<AMAVal && prevClose>prevAMAVal) { trade.PositionClose(_Symbol); trade.Sell(lotSize,_Symbol,Bid,0,0,NULL); } } } //+------------------------------------------------------------------+
このコードの違いは、適応型移動平均指標のハンドルを返すiAMA関数を使用していることと、そのパラメータです。
- symbol:銘柄(現在の銘柄に_Symbolを使用)
- period:時間枠(ユーザー入力を使用、デフォルト値1時間)
- ama_period:適応移動平均の期間
- fast_ma_period:高速MAの期間
- slow_ma_period:低速MAの期間
- ama_shift:水平方向のシフト(0を使用)
- applied_price:価格の種類(終値)
AMA指標の結果を見るには、同じ期間でバックテストを行います。
- ロットサイズ =1
- 時間枠 = 1時間
- MAperiod = 50
- 高速MA = 5
- 低速MA = 100
結果は次の通りです。
AMA指標をテストした後、次のような数字を見ることができます。
- 純利益:3638.20 (36.39%)
- バランスDD(相対):22.48%
- エクイティDD(相対):35.53%
- プロフィットファクター:1.31
- 予想ペイオフ:35.67
- リカバリーファクター:0.65
- シャープレシオ:0.86
二重指数移動平均(iDEMA)
この部分では、移動平均のもう1つのタイプであるDEMA (Double Exponential Moving Average)テクニカル指標を確認します。これは、Patrick Mulloyが開発したトレンドフォロワー指標です。指標の計算でわかるように、この指標の主な目的は、EMAの遅れを減らし、市場の動きに反応しやすくすることです。
この指標は、この移動平均線に対する価格の相対的な位置 を検出することで、トレンドやトレンドの転換点を特定するために使用できます。指標の計算手順を以下に示します。
1.最初の指数移動平均(EMA)の計算
EMA1 = n期間の価格のEMA
2.EMA1のEMAの計算
EMA2 = EMA1のEMA
3.DEMAの計算
DEMA = (2 * EMA1) - EMA2
指標をよく理解するために手動で計算したのですが、ご存知のように、この指標も手動で計算する必要はありません。この指標はMetaTrader 5内蔵の多くのテクニカル指標の1つです。前回作成したのと同じ取引システムを作成する必要がありますが、今回はDEMAを使用して、他のタイプと比較した結果をテストします。この取引システムは、同じようにクロスオーバーに基づいて売買する注文を実行しますが、今回は価格とDEMA指標の間のクロスオーバーになります。次がシグナルです。
買いシグナル:
終値が二重指数移動平均(DEMA)を上回っている。
かつ、前回の終値が前回のDEMA値を下回っている。
売りシグナル:
終値がDEMA値を下回っている。
かつ、前回の終値が前回のDEMA値を上回っている。
以下は、この取引システムの完全なコードですが、iDEMA関数を使用して二重指数移動平均指標のハンドルを返すという若干の違いがあり、そのパラメータは次のとおりです。
- symbol:銘柄(現在の銘柄に_Symbolを使用)
- period:時間枠(ユーザー入力を使用、デフォルト値1時間)
- ma_period:移動平均期間(ユーザー入力を使用、デフォルト値50)
- ma_shift:水平方向のシフト(0を使用)
- applied_price:価格の種類(移動平均の計算では終値を使用)
以下の1ブロックのコードのようになります。
//+------------------------------------------------------------------+ //| iDEMA_System.mq5 | //+------------------------------------------------------------------+ #include <Trade\Trade.mqh> input double lotSize = 1; input ENUM_TIMEFRAMES timeFrame = PERIOD_H1; input int MAPeriod= 50; int DEMA; int barsTotal; CTrade trade; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { DEMA = iDEMA(_Symbol, timeFrame, MAPeriod,0, PRICE_CLOSE); barsTotal=iBars(_Symbol,timeFrame); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { MqlRates priceArray[]; double myDEMAArray[]; double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits); ArraySetAsSeries(priceArray,true); ArraySetAsSeries(myDEMAArray,true); int Data=CopyRates(_Symbol,timeFrame,0,3,priceArray); CopyBuffer(DEMA,0,0,3,myDEMAArray); double lastClose=(priceArray[1].close); double DEMAVal = NormalizeDouble(myDEMAArray[1],_Digits); double prevClose=(priceArray[2].close); double prevDEMAVal = NormalizeDouble(myDEMAArray[2],_Digits); int bars=iBars(_Symbol,timeFrame); if(barsTotal != bars) { barsTotal=bars; if(lastClose>DEMAVal && prevClose<prevDEMAVal) { trade.PositionClose(_Symbol); trade.Buy(lotSize,_Symbol,Ask,0,0,NULL); } if(lastClose<DEMAVal && prevClose>prevDEMAVal) { trade.PositionClose(_Symbol); trade.Sell(lotSize,_Symbol,Bid,0,0,NULL); } } } //+------------------------------------------------------------------+
コードをコンパイルした後、他のタイプで使用したのと同じ期間をバックテストします。この指標の設定または入力は次のようになります。
- ロットサイズ = 1
- 時間枠 = 1時間
- MA期間 = 50
テストを実行すると、次のような結果が得られます。
iDEMAをテストした結果は、以下のようになります。
- 純利益: - 961.60 (- 9.62%)
- バランスDD(相対):39.62%
- エクイティDD(相対):41.15%
- プロフィットファクター:0.97
- 期待ペイオフ: - 3.12
- リカバリーファクター: - 0.18
- シャープレシオ: - 0.21
三重指数移動平均(iTEMA)
次に、別の移動平均タイプである三重指数移動平均(TEMA)を特定します。これは、短期取引に適した指標の応答性を高めるために、Patrick Mulloyによって開発されました。本指標では、トリプルEMA、シングルEMA、ダブルEMAを使用しています。そのため、この指標は、先ほど述べたように、より反応しやすい価格に近づくことになります。二重指数移動平均を使用したのと同じように、TEMAも価格に対する反応が早いため、トレンドやターニングポイント、トレンドの変化を特定するために使用することができます。
以下は、このTEMA指標の計算手順です。
1.最初の指数移動平均(EMA)の計算
EMA1 = n期間の価格のEMA
2.EMA1のEMAの計算
EMA2 = EMA1のEMA
3.EMA2のEMAの計算
EMA3 = EMA2のEMA
4.TEMAの計算
DEMA = (3 * EMA1) - (3 * EMA2) + (EMA3)
MetaTrader 5に用意されているテクニカル指標から、この指標を手動で計算することなく挿入することができます。その後、このTEMA指標を使用して取引システムを作成し、テストし、その結果を他のタイプと比較します。以下は、以前と同じようにこの取引システムを作成するための完全なコードです。ただし、iTEMA関数を使用して三重指数移動平均指標のハンドルを返す点が異なります。
//+------------------------------------------------------------------+ //| iTEMA_System.mq5 | //+------------------------------------------------------------------+ #include <Trade\Trade.mqh> input double lotSize = 1; input ENUM_TIMEFRAMES timeFrame = PERIOD_H1; input int MAPeriod= 50; int TEMA; int barsTotal; CTrade trade; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { TEMA = iTEMA(_Symbol, timeFrame, MAPeriod,0, PRICE_CLOSE); barsTotal=iBars(_Symbol,timeFrame); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { MqlRates priceArray[]; double myTEMAArray[]; double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits); ArraySetAsSeries(priceArray,true); ArraySetAsSeries(myTEMAArray,true); int Data=CopyRates(_Symbol,timeFrame,0,3,priceArray); CopyBuffer(TEMA,0,0,3,myTEMAArray); double lastClose=(priceArray[1].close); double TEMAVal = NormalizeDouble(myTEMAArray[1],_Digits); double prevClose=(priceArray[2].close); double prevTEMAVal = NormalizeDouble(myTEMAArray[2],_Digits); int bars=iBars(_Symbol,timeFrame); if(barsTotal != bars) { barsTotal=bars; if(lastClose>TEMAVal && prevClose<prevTEMAVal) { trade.PositionClose(_Symbol); trade.Buy(lotSize,_Symbol,Ask,0,0,NULL); } if(lastClose<TEMAVal && prevClose>prevTEMAVal) { trade.PositionClose(_Symbol); trade.Sell(lotSize,_Symbol,Bid,0,0,NULL); } } } //+------------------------------------------------------------------+
コンパイルして実行した後、同じ期間のバックテストをおこない、その結果を他の移動平均のタイプと比較することができます。以下は、このテストプロセスですべてのパラメータを修正するために使用される設定または入力です。
- ロットサイズ = 1
- 時間枠 = 1時間
- MA期間 = 50
このテストを実行し、完了すると、以下のような結果が得られます。
私たちが研究しなければならないのは、次の数字です。
- 純利益: - 3973.10 (- 39.74%)
- バランスDD(相対):63.98%
- エクイティDD(相対):66.06%
- プロフィットファクター:0.90
- 期待ペイオフ: - 10.59
- リカバリーファクター: - 0.52
- シャープレシオ: - 0.83
フラクタル適応移動平均(iFrAMA)
この記事で確認する必要がある移動平均の最後のタイプは、ジョン・F・エーレルスが開発したフラクタル適応移動平均(FrAMA)指標です。これは、トレンドフォローの指標であり、市場価格はフラクタルであると想定されています。また、トレンドやターニングポイントを検出するためにも使用できます。計算方法は以下の通りです。
この指標は、MetaTrader 5に用意されているテクニカル指標から挿入することができます。次に、同じ戦略で同じ取引システムを作成しますが、ここでは代わりにFrAMA指標を使用して、他のタイプとテストした後の結果を比較します。戦略は、価格とFrAMA指標のクロスオーバーで、価格がFrAMAを上回っているときは買いシグナルとなり、価格がFrAMAを下回っているときは売りシグナルとなります。
買いシグナル:
終値がフラクタル順応移動平均(FrAMA)値を上回っっている。
かつ、前回の終値が前回のFrAMA値を下回っている。
売りシグナル:
終値がFrAMA値を下回っている。
かつ、前回の終値が前回のFrAMA値を上回っている。
以下は、この取引システムを作成するための完全なコードです。他のタイプで前に述べたものと同じですが、フラクタル適応移動平均のハンドルを返すために(iFrAMA)関数を使用し、そのパラメータは次のとおりです。
- symbol:銘柄(現在の銘柄に_Symbolを使用)
- period:時間枠(ユーザー入力を使用、デフォルト値1時間)
- ma_period:移動平均期間(ユーザー入力を使用、デフォルト値50)
- ma_shift:水平方向のシフト(0を使用)
- applied_price:価格の種類(終値を使用)
//+------------------------------------------------------------------+ //| iFrAMA_System.mq5 | //+------------------------------------------------------------------+ #include <Trade\Trade.mqh> input double lotSize = 1; input ENUM_TIMEFRAMES timeFrame = PERIOD_H1; input int MAPeriod= 50; int FrAMA; int barsTotal; CTrade trade; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { FrAMA = iFrAMA(_Symbol, timeFrame, MAPeriod,0, PRICE_CLOSE); barsTotal=iBars(_Symbol,timeFrame); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { MqlRates priceArray[]; double myFrAMAArray[]; double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits); ArraySetAsSeries(priceArray,true); ArraySetAsSeries(myFrAMAArray,true); int Data=CopyRates(_Symbol,timeFrame,0,3,priceArray); CopyBuffer(FrAMA,0,0,3,myFrAMAArray); double lastClose=(priceArray[1].close); double FrAMAVal = NormalizeDouble(myFrAMAArray[1],_Digits); double prevClose=(priceArray[2].close); double prevFrAMAVal = NormalizeDouble(myFrAMAArray[2],_Digits); int bars=iBars(_Symbol,timeFrame); if(barsTotal != bars) { barsTotal=bars; if(lastClose>FrAMAVal && prevClose<prevFrAMAVal) { trade.PositionClose(_Symbol); trade.Buy(lotSize,_Symbol,Ask,0,0,NULL); } if(lastClose<FrAMAVal && prevClose>prevFrAMAVal) { trade.PositionClose(_Symbol); trade.Sell(lotSize,_Symbol,Bid,0,0,NULL); } } } //+------------------------------------------------------------------+
このEAをコンパイルして実行した後、FrAMA指標を使用して、以下の同じ設定または入力でこの戦略をテストします。
- ロットサイズ:1
- 時間枠:1時間
- MA期間:50
このEAを他の移動平均線と同じ期間でテストしたところ、次のような結果が得られました。
見ての通り、最も重要な数字は次です。
- 純利益: - 2993.70 (- 29.94%)
- バランスDD(相対):73.28%
- エクイティDD(相対):74.81%
- プロフィットファクター:0.93
- 期待ペイオフ: - 6.45
- リカバリーファクター: - 0.33
- シャープレシオ: - 0.46
単純移動平均(SMA)の結果との比較
この部分では、言及したすべての移動平均タイプの結果の比較を提供します。可能な限り最良の結果を提供するように努めますが、最適化して期間を変更すると、すべての移動平均が異なる結果をもたらす可能性があることを知っておいてください。 移動平均は、指標の設定と市場の状況に基づいて異なる結果が得られることがわかっているため、テスト期間を使用することもできます。
ここでの主な目的は、可能な限り同じ条件を提供し、私たちの視点から選択できるベストな設定で、他よりも優れたタイプがあるかどうかを確認することです。しかし、私たちが何を求めているかを理解していただくためには、最も重要な指標が最高のパフォーマンスを発揮しているところをご覧いただく必要があります。
- 純利益:高いほど良い
- ドローダウン(DD):低いほど良い
- 利益率:高いほど良い
- 予想損益:高いほど良い
- リカバリーファクター:高いほど良い
- シャープレシオ:高いほど良い
さて、次の表を通して、前回の単純移動平均の結果と、前回の文脈に基づく他の移動平均の種類とを比較してみましょう。
測定 | SMA | AMA | DEMA | TEMA | FrAMA |
---|---|---|---|---|---|
純利益 | 2700.30 (27%) | 3638.20 (36.39%) | - 961.60 (- 9.62%) | - 3973.10 (- 39.74%) | - 2993.70 (- 29.94%) |
バランスDD(相対) | 37.07% | 22.48% | 39.62% | 63.98% | 73.28% |
エクイティDD(相対) | 41.76% | 35.53% | 41.15% | 66.06% | 74.81% |
利益率 | 1.10 | 1.31 | 0.97 | 0.90 | 0.93 |
ペイオフ期待値 | 12.68 | 35.67 | - 3.12 | - 10.59 | - 6.45 |
リカバリーファクター | 0.45 | 0.65 | - 0.18 | - 0.52 | - 0.33 |
シャープレシオ | 0.57 | 0.86 | - 0.21 | - 0.83 | - 0.46 |
すべてのテスト結果によると、設定とテスト期間に基づいて最高のパフォーマンスを発揮する2つのタイプがあります。単純移動平均と適応移動平均です。最も優れているのは適応移動平均で、次を備えています。
- 最高の純利益
- 最低のバランスDD(相対)
- 最低のエクイティDD(相対)
- 最高の利益要因
- 最高の期待報酬
- 高いリカバリーファクター
- 高いシャープレシオ
設定や戦略をより最適化することで、より良い結果が得られる可能性があることは前述したが、ここでの目的は、テストプロセスを理解し、実際の例で適用することです。
結論
この記事では、以下の移動平均タイプのパフォーマンス結果を検討しました。
- アダプティブ移動平均(AMA)
- 二重指数移動平均(DEMA)
- 三重指数移動平均(TEMA)
- フラクタル適応移動平均(FrAMA)
各タイプの取引システムを作成し、その結果を最も一般的な移動平均のタイプである単純移動平均と比較しました。テスト結果によると、単純移動平均と適応型移動平均で最も良い結果が得られ、トップは適応型移動平均(AMA)でした。勝者を特定するために、以下の指標を分析比較しました。
- 純利益
- ドローダウン(DD)
- 利益率
- ペイオフ期待値
- リカバリーファクター
- シャープレシオ
取引において、テストは非常に重要なテーマです。より多くの戦略でテストすることをお勧めします。戦略そのものを評価するだけでなく、テストを重ねるごとに理解が深まり、思いがけない洞察を得られることもあります。
この記事をお読みいただき、ありがとうございました。この記事が読者にとって有益であり、読者の知識に付加価値を与えるものであったことを願っています。RSI、MACD、ストキャスティクス、ボリンジャーバンドなど、人気のあるテクニカル指標に基づく取引システムの作成に関する他の記事をお読みになりたい場合は、出版物から私の記事をチェックしてみてください。
MetaQuotes Ltdにより英語から翻訳されました。
元の記事: https://www.mql5.com/en/articles/13130





- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索