古いトレンドトレーディング戦略の再検討:2つのストキャスティクス、MAとフィボナッチ
はじめに:戦略の詳細
これは純粋なテクニカル戦略で、シグナルとターゲットを出すためにいくつかのテクニカル指標とツールを使用します。戦略の構成要素は次の通りです。
- 14期間のストキャスティクス、
- 5期間のストキャスティクス、
- 200期間の移動平均線、
- フィボナッチ予測ツール(目標設定用)。
ストキャスティックスは、トレーダーや投資家が金融商品の値動きの勢いや強さを測定するために使用する一般的なテクニカル分析ツールです。1950年代後半にジョージ・レーンによって開発されました。0から100の間で区切られ、下限線に近い値を売られ過ぎ(強気バイアス)、上限線に近い値を買われ過ぎ(弱気バイアス)と呼びます。
日足時間枠の5期間ストキャスティクスは次のように
定義されます。
ここで、HighとLowはそれぞれ過去5日間の最高値と最安値であり、%Dは%KのN日移動平均(%Kの直近N個の値)です。通常、これは単純移動平均ですが、より最近の値を標準化されずに加重するために指数移動平均とすることもできます。%Dを単独で使用する場合、有効なシグナルは1つだけで、%Dと分析されたセキュリティの間の相違です。
移動平均は、指定された期間の価格データを平滑化するのに役立つ、一般的に使用される統計計算で、金融、経済、信号処理などさまざまな分野で広く使われています。金融市場では、移動平均線はテクニカル分析で頻繁に使用され、トレンドを特定し、売買シグナルを生成します。
移動平均は、ある時間枠における一連の価格の平均(平均値)を取り、新しいデータが利用可能になるとそれを更新することによって計算されます。新しいデータポイントが追加されるたびに、最も古いデータポイントは削除され、その結果、最新の価格を反映した「移動」平均が得られます。
戦略の実施
この戦略の取引ルールは以下の通りです。
- 両方のストキャスティクスが同時に売られ過ぎのレベルに達し、跳ね返された後、(同時期に)売られ過ぎのレベルに戻るたびに、買いシグナルが発生します。すべてのプロセスは、相場が200期間移動平均線を上回っている間におこなわなければなりません。1番目のターゲットは、ストキャスティックスが最初に底を打ったときの安値と、2回目に底を打ったときの安値からフィボナッチプロジェクションツールを使って設定します。従って、1番目のターゲットは61.8%の予測であり、2番目のターゲットは100.0%の予測です。
- 両方のストキャスティクスが同時に買われすぎの水準に達し、跳ね返された後、再び買われすぎの水準に戻る(ほぼ同時期)たびに、ショートシグナルが発生します。すべてのプロセスは、相場が200期間移動平均線を下回っている間に行わなければならない。1番目のターゲットは、ストキャスティクスが最初に頂点に達したときの高値と、2回目に頂点に達したときの高値からフィボナッチプロジェクションツールを使って設定します。従って、1番目のターゲットは61.8%の予測であり、2番目のターゲットは100.0%の予測です。
(フィボナッチレベルごとにストップレベルを設定するよう、戦略を変更しました。)
次の図は弱気シグナルを示しています。
結局のところ、結果は市場によって異なる可能性があり、現在の結果が安定するとは限りません。ある時期には有効でも、ある時期にはパフォーマンスが低下することもあります。
戦略のストップは、リスクリワード比率が2.0になるようにターゲットの半分に設定するか、市場が移動平均線をブレイクするたびに設定します。
金融では、フィボナッチリトレースメントは、支持線と抵抗線を決定するためのテクニカル分析の手法です。フィボナッチとは、フィボナッチ数列にちなんで命名されたもので、その比率は、トレンドが元の方向に継続する前に、市場が動きの一部をリトレースする傾向にある価格水準を示しています。
フィボナッチリトレースメント予測は、チャート上の2つの極端なポイントを取り、垂直距離をフィボナッチ比率で割ることによって作成されます。0%はリトレースメントの開始とみなされ、100%は移動前の元の価格への完全な反転です。チャートには、これらの価格水準に対して水平線が引かれ(このEAにはない)、支持線と抵抗線となっています。
一般的なレベルは23.6%、38.2%、50%、61.8%です。
結果
これは収益性の高い戦略ではありますが、市場によって異なるため、現在の結果が安定するとは限りません。ある時期には有効でも、ある時期にはパフォーマンスが低下することもあります。 使用する前に戦略をテストし、シフト日数や時間帯など、最適なアチーブメントを得るように値を変更してください。
これを使って、すべてのデータをシフトオーバーすることができます。
int Highest = iHighest(Symbol(),my_timeframe,MODE_CLOSE,shift,1); double High0=iHigh(Symbol(),my_timeframe,0); int Lowest = iLowest(Symbol(),my_timeframe,MODE_CLOSE,shift,1); double Low0=iLow(Symbol(),my_timeframe,0);
ただし、テスト上の理由から、より小さなシフト値(例えば300)を使用します。
次は、シフト=300、期間=30分、2013年から2023年(6月20日)まで、リスク2%の場合の結果です。
金融では、シャープレシオ(シャープ指数または報酬対変動率としても知られる)は、そのリスクを調整した後、無リスク資産と比較した証券やポートフォリオなどの投資のパフォーマンスを測定します。これは、投資リターンとリスクフリーリターンの差を投資リターンの標準偏差で割ったものと定義されます。投資家がリスクの増加1単位あたりで受け取る追加的なリターンの額が表されています。
コード
OnInitで、使用する技術を宣言します。まずハンドルです。
void OnInit() { Stochastic_handle1 = iStochastic(_Symbol, PERIOD_CURRENT, Signal_0_Stoch_PeriodK, Signal_0_Stoch_PeriodD, Signal_0_Stoch_PeriodSlow, MODE_SMA, STO_LOWHIGH); Stochastic_handle2 = iStochastic(_Symbol, PERIOD_CURRENT, Signal_1_Stoch_PeriodK, Signal_1_Stoch_PeriodD, Signal_1_Stoch_PeriodSlow, MODE_SMA, STO_LOWHIGH); //--- create handle of the indicator iMA handle_iMA=iMA(_Symbol,PERIOD_CURRENT,Inp_MA_ma_period,Inp_MA_ma_shift, Inp_MA_ma_method,Inp_MA_applied_price); //Test Alert("Expert Advisor has been launched"); }
このコードでは、ストキャスティクスのハンドルを作成します。このハンドルはStochastic_handle1と呼ばれます。ハンドルの作成にはiStochastic()関数を使用します。関数に渡されるパラメータは、銘柄、現在の期間、%Kラインの期間、%Dラインの期間、低速ラインの期間とモード、ストキャスティクスのタイプ(低/高)です。
このコードは、指定されたパラメータで現在の銘柄の移動平均(MA)を計算するために使用されます。handle_iMA変数は、MAの計算結果を格納します。計算に使用されるパラメータは、銘柄、現在の期間、MA期間、MAシフト、MA手法、および適用価格です。銘柄は、MAが計算される通貨ペアまたは証券です。現在の期間は、MAが計算されているチャートの時間枠です。MA期間は、MAを計算するために使用されるバーの数です。MAシフトは、MA計算をシフトさせるバーの数です。MA法は、単純、指数、平滑化、線形加重などのMA計算のタイプです。適用価格は、終値、始値、高値、安値、中央値、標準値、加重値など、MA計算に使用される価格タイプです。
OnInitの前に、外部で宣言されたすべてのパラメーターを入力しなければなりません。
OnTickでは、各ティック値を取得するために、次のようにします。
MqlTick tick; SymbolInfoTick(_Symbol,tick);
このコードは、指定された銘柄のティックデータを取得するために使用されます。最初の行ではMqlTick型のtickという変数を宣言します。2行目ではSymbolInfoTick()関数を呼び出します。パラメータは銘柄名とティック変数の2つです。この関数は、指定された銘柄のティックデータを取得し、ティック変数に格納します。
フィボナッチリトレースメントレベルをシミュレートするには、次を使用します。
int Highest = iHighest(Symbol(),my_timeframe,MODE_CLOSE,shift,1); double High0=iHigh(Symbol(),my_timeframe,0); int Lowest = iLowest(Symbol(),my_timeframe,MODE_CLOSE,shift,1); double Low0=iLow(Symbol(),my_timeframe,0); double highestValue = iHigh(Symbol(),my_timeframe,Highest); double lowestValue = iLow(Symbol(),my_timeframe,Lowest); // Obtener el valor más alto y más bajo de la barra actual double currentHigh = High0; double currentLow = Low0; // Obtener el valor más alto y más bajo de la barra anterior double previousHigh = highestValue; double previousLow = lowestValue; double level0s = currentHigh; double level1s = currentHigh - (currentHigh - previousLow) * 0.236; double level2s = currentHigh - (currentHigh - previousLow) * 0.382; double level3s = currentHigh - (currentHigh - previousLow) * 0.618; double level4s = previousLow; double level0b = currentLow; double level1b = currentLow + (-currentLow + previousHigh) * 0.236; double level2b = currentLow + (-currentLow + previousHigh) * 0.382; double level3b = currentLow + (-currentLow + previousHigh) * 0.618; double level4b = previousHigh;
MQL5言語のこのコードは、与えられた銘柄と期間の最高値と最低値を決定するために使用されます。コードの最初の2行では、銘柄と期間の最高値を変数Highestに代入し、与えられたシフト=0における銘柄と期間の最高値を変数High0(現在のローソク足)に代入します。次の2行のコードでは、銘柄と期間の最低値を変数Lowestに代入し、与えられたシフト=0における銘柄と期間の最低値を変数Low0に代入します。
何本のローソク足を振り返るかは、シフトを使って選択します。
MAには次を使用します。
//--- double array_ma[]; ArraySetAsSeries(array_ma,true); int start_pos=0,count=3; if(!iGetArray(handle_iMA,0,start_pos,count,array_ma)) return;
このコードは、ハンドルから移動平均の配列を取得するために使用されます。最初の行ではarray_maという配列を宣言します。この配列は移動平均を格納するのに使われます。2行目では、配列を系列として設定します。3行目と4行目では、start_posとcountという2つの整数変数を宣言します。これらは、ハンドルから取り出す開始位置と要素数を指定するのに使われます。5行目では、iGetArray関数を使ってハンドルから移動平均を取り出し、array_maに格納します。検索に失敗した場合、この関数はfalseを返します。
次を(OnInitの外側で)使用します。
bool iGetArray(const int handle,const int buffer,const int start_pos, const int count,double &arr_buffer[]) { bool result=true; if(!ArrayIsDynamic(arr_buffer)) { //if(InpPrintLog) PrintFormat("ERROR! EA: %s, FUNCTION: %s, this a no dynamic array!",__FILE__,__FUNCTION__); return(false); } ArrayFree(arr_buffer); //--- reset error code ResetLastError(); //--- fill a part of the iBands array with values from the indicator buffer int copied=CopyBuffer(handle,buffer,start_pos,count,arr_buffer); if(copied!=count) { //--- if the copying fails, tell the error code //if(InpPrintLog) PrintFormat("ERROR! EA: %s, FUNCTION: %s, amount to copy: %d, copied: %d, error code %d", __FILE__,__FUNCTION__,count,copied,GetLastError()); //--- quit with zero result - it means that the indicator is considered as not calculated return(false); } return(result); }
このコードは、指標バッファの一部を配列にコピーするために使用されます。ハンドル、バッファ、開始位置、カウント、配列バッファの5つのパラメータを受け取ります。まず配列バッファが動的かどうかを確認し、動的でない場合はエラーメッセージを表示します。その後、エラーコードをリセットし、バッファを配列バッファにコピーします。コピーされた量がカウントと等しくない場合は、エラーメッセージを表示し、falseを返します。そうでない場合はtrueを返します。
エラーを表示し、その結果をグラフで表示するには、次のようにします。
string text=""; for(int i=0; i<count; i++) text=text+IntegerToString(i)+": "+DoubleToString(array_ma[i],Digits()+1)+"\n"; //--- Comment(text);
このコードは、MQL5言語でdouble型の配列の値を出力するために使用されます。まずtextという文字列変数を宣言し、それを空文字列に設定します。次に、forループを使って配列を繰り返し、変数「i」をループカウンタとして使用します。各反復ごとに、「i」の値はIntegerToString()関数を使って文字列に変換され、そのインデックスの配列の値はDoubleToString()関数を使って文字列に変換されます。Digits()関数は、double値を文字列に変換する際に使用する小数点以下の桁数を決定します。変換された値はtext文字列に連結され、各値の後に改行文字が追加されます。最後に、Comment()関数を使ってtext文字列を出力します。
両方のストキャスティクスについても同じことをおこないます。
同時に複数の注文を出さないように条件を設定します。
int total = PositionsTotal(); if(total==0) { ...code } if(total>0) { ...code }
注文するには次を使用します。
if(!trade.Buy(get_lot(tick.bid),_Symbol,tick.bid,newStopLossLevelb1,newTakeProfitLevelb2)) { //--- failure message Print("Buy() method failed. Return code=",trade.ResultRetcode(), ". Code description: ",trade.ResultRetcodeDescription()); } else { Print("Buy() method executed successfully. Return code=",trade.ResultRetcode(), " (",trade.ResultRetcodeDescription(),")"); }
ここでは、tick.bidを使用し、SLとTPを使用します。TPはシフト期間の最高値となり、SLは実際のローソク足の最下位となります。
価格がMAを超えたときに注文をクローズするには、次のようにします。
if(rates[1].close >array_ma22[0]) { trade.PositionClose(_Symbol,5); Print("cerro"); return; } else return; }
TPとSLを変更するには、次を使用します。
//--- setting the operation parameters request.action =TRADE_ACTION_SLTP; // type of trade operation request.position=position_ticket; // ticket of the position request.symbol=position_symbol; // symbol request.sl =newStopLossLevelss; // Stop Loss of the position request.tp =newTakeProfitLevelss; // Take Profit of the position request.magic=Expert_MagicNumber; // MagicNumber of the position //--- output information about the modification PrintFormat("Modify #%I64d %s %s",position_ticket,position_symbol,EnumToString(type)); //--- send the request if(!OrderSend(request,result)) PrintFormat("OrderSend error %d",GetLastError()); // if unable to send the request, output the error code //--- information about the operation PrintFormat("retcode=%u deal=%I64u order=%I64u",result.retcode,result.deal,result.order);
フリーズレベルとストップレベルを使用することを忘れないでください。また、TPとSLの両方を変更することを考慮に入れてください。
すべてのフィボナッチレベルにストップロスレベルを追加したので、結果は最初のスタートとは異なるかもしれません。コードを読んだ後で、コードを修正しそれらのレベルを変更することができます。
結論
この戦略では、ある期間では利益を上げることができますが、他の状況下ではパフォーマンスが低下することもあります。2008年から2014年の危機、そして2020年のコロナ禍の際、この戦略は貧弱でした。
この戦略は、危機的な時期以外、トレンドの時期によく機能します。
シャープレシオは約4です。これは、この戦略が少なくともロバストであることを意味し、リスク調整後のパフォーマンスを評価するファイナンスは非常に優れており、優良に近いと考えられます。
この戦略は、他の戦略を補完するものとして使用できます。
好みに合わせて変更すれば、より良い結果が得られると思います。
この記事の目的は、戦略を理解してもらうことであることを覚えていてください。この戦略は実用目的ではありません。使用する場合は自己責任でお願いします。
より多くの時間枠と他の銘柄でこのボットをテストすることをお勧めします。
他の期間を使えば、おそらく違った結果になるでしょう。
MetaQuotes Ltdにより英語から翻訳されました。
元の記事: https://www.mql5.com/en/articles/12809





- 無料取引アプリ
- 無料の24時間外国為替VPS
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索