価格速度測定方法

22 7月 2019, 08:24
Alexander Fedosov
0
294

目次

イントロダクション

相場調査と相場分析には、複数の異なるアプローチがあります。 主なものには、テクニカルとファンダメンタルがあります。 テクニカル分析では、トレーダーは、価格、ボリュームなど、相場に関連する数値データとパラメータを収集、処理、分析します。 ファンダメンタルズでは、トレーダーは相場に直接的または間接的に影響を与えるイベントやニュースを分析します。 ファンダメンタルデータを分析する際の主な問題は、相場への影響に関するイベントの解釈です。 このような解釈は、トレーダーの意見や期待に影響を受ける可能性があります。 それどころか、テクニカルデータは、通常、様々な解釈を生み出しません。 しかし、テクニカル分析の結果を評価する際にも人的要因が存在します。


知覚の問題

相場のテクニカル分析と言えば、数学や物理学など、様々な科学分野の評価システムを使うことです。 テクニカル分析における数学の必要性は明らかであり、相場に様々な物理現象を適用することはより興味深いです。 そこで本稿では、このようなよく知られた物理現象を、時間単位ごとの移動の尺度である速度として考察します。 外国為替やその他のチャートを見ると、現在の価格の方向性だけでなく、特に高値のボラティリティ期間中に、その速度もはっきりと見ることができます。 誰もがチャートを視覚的に分析し、現在の価格の変化が速いか遅いかを判断することができます。 しかし、このような視覚的な推定は、人々の認識の差に対して主観的なままです。

現実の生活における簡単な例としては、小型車が一見遅い速度で移動するように見え、大型トラックが早い速度で移動するように見える視覚的なトリックなどがあります。 この問題は、数字ですべてを示す計器によって解決されます。そうすれば、絶対に同じです。

価格速度測定方法

価格速度を測定するための様々なアプローチを検討する前に、速度が何か定義しましょう。

Wikipediaによると:

物体の速度は、参照フレームに対する位置の変化の速度であり、時間の関数です。.. 速度は物理ベクトル量です。これを定義するには、大きさと方向の両方が必要です。 

この定義をFXに適用するにはどうすればよいでしょうか。 最も簡単な方法は、物体を価格に置き換え、足またはロウソクが形成される時間を参照フレームとして設定することです。 価格チャートの観点からは、次のようになります。


図1. H1時間枠で日足のローソク足として価格を表示する

この場合、シンプルな速度測定は次のようになります。

平均速度 = (終値 — 始値) / 時間

時間の経過に関する正確な観察と結論は以下の通りです。

  • 価格が1時間あたりに通過するポイントの平均数を定義しました。 しかし、測定は1本のロウソクの枠組みの中で行われ、この時間枠の全体的なトレンドの画像を得ることはできません。
  • ただし、1 時間あたりのポイントから 1 分あたりのポイント、5 分などのポイントに変換すると、この H1 時間内の価格の動きに関するより貴重なデータが得られます。
  • したがって、次の 2 つの結論は明らかです。低い時間枠で速度を決定する方が、より高い時間枠で行うより便利です。 価格の動きを測定することによって、現在の時間枠の平均速度を測定する場合, ロウソクを使用する必要があります。
最後に、このようなシンプルな方法で速度を測定する主なポイントは、代わりに最終的な平均結果のみを表示するロウソク足内の価格ダイナミクスに関する詳細なデータを提供しありません。 例えば、H1ロウソク足の平均速度を知って、価格が最初から時間の終わりまでに大幅に減少した高値だったことを定義することはできません。

わかりやすくするために、上記の結論を示す例を出します。 図2は、Average Speedインジケータを使用して計算された1分あたりの平均速度を持つH1ロウソクを示します。 ここでは、毎分2.53ポイントに等しいです。

図2. EURUSD H1 の平均速度の計算

では、M15で同じロウソクを見てみましょう。


図3. EURUSD H15 の平均速度の計算

図3は、選択した時間の最初の15分間(Average speedは6.93)の動きが強かり、その後大幅に減速したことを示します。 もちろん、平均速度の 4 つの値をすべて合計すると、1 分あたり同じ 2.53 ポイントが得られます。 したがって、ロウソク足をコンポーネントに分割すると、そのダイナミクスに関する多くのデータを明らかにすることができます。

H1 ロウソク足を M1 間隔に分割すると、さらに多くのデータが得されます。

図4. EURUSD M1 の平均速度の計算

M1時間枠のポイントで移動速度を計算するためのオプションを検討する際、さらに別の測定方法があります。

瞬間的な(現在の)価格速度を伴います。 一方で、その値は常に可能な限り関連性があります。 一方、ティック価格の変化で動作するサンプルインジケータは次のようになります。

図5. 瞬間的な価格速度インジケータ

明らかに、外国為替トレードでその後の使用のそのような混沌とした(関連する)データの評価は挑戦的なタスクです。

周知のように、圧倒的多数のインジケータは、価格またはその分析器の派生品です。 これらは、価格速度で動作するよく知られたインジケータです:

  • モメンタムは、一定期間の価格変化の量を測定します。高いモメンタムや低いモメンタム値は、現在のトレンドの継続を示唆しています。インジケータからの大きな偏差は、特定の方向の現在の高値価格速度を表します。
  • ADXトレンドインジケータ. 平均方向移動指数は、現在のトレンドの強さを示します。 実際には、現在の平均速度が表示されます。

測定方法に基づくトレード戦略の策定

したがって、さまざまな価格速度測定をテストする目的は、3 つの主要なグループに分けられます。

  • 時間単位あたりの通過ポイントの比率としての平均速度の直接標準測定。
  • ティック数に渡されたポイント数の比率としてティックを使用して速度を測定します。
  • トレンドフォローやその他のインジケータを使用した間接速度測定。

トレード戦略 1

Average Speedインジケータを使用して、時間単位あたりの通過点数として測定速度に基づいて最初の方法をテストするには、インジケータが時間の単位当たりのポイント数を表示するので、トレンド方向を示すフィルタをテストされた戦略に追加する必要があります。

そのようなフィルタとして調整ADXとMACD(CAM)インジケータを使用することにしました。 トレード戦略は次のようになります。

パラメータ 詳細
適用されたインジケータ Average Speed
適用されたインジケータ 協調ADXとMACD(CAM) 
時間枠 任意 
買い条件 ローソク足が緑色で、平均速度の値が閾値を超える(パラメータで事前に設定されています)。
売り条件 ロウソクが赤色で、平均速度の値が閾値を超える(パラメータで事前に設定されています)
決済条件   テイクプロフィット/ストップロス

図6は、ロングとショートのオープンの可視化

図6. トレード戦略のエントリー条件

この戦略は、次の方法で実装されます。

//+------------------------------------------------------------------+
//| EA inputs                                                        |
//+------------------------------------------------------------------+
input string               InpEaComment         =  "Strategy #1"; // EA Comment
input int                  InpMagicNum          =  1111;          // Magic number
input double               InpLot               =  0.1;           // Lots
input uint                 InpStopLoss          =  400;           // StopLoss in points
input uint                 InpTakeProfit        =  500;           // TakeProfit in points
input uint                 InpSlippage          =  0;             // SLippage in points
input ENUM_TIMEFRAMES      InpInd_Timeframe     =  PERIOD_H1;     // Timeframe for the calculation
//--- Average Speed indicator parameters
input int                  InpBars              =  1;             // Days
input ENUM_APPLIED_PRICE   InpPrice             =  PRICE_CLOSE;   // Applied price
input double               InpTrendLev          =  2;             // Trend Level
//--- CAM indicator parameters
input uint                 InpPeriodADX         =  10;            // ADX period
input uint                 InpPeriodFast        =  12;            // MACD Fast EMA period
input uint                 InpPeriodSlow        =  26;            // MACDSLow EMA period
//---
CEngine        engine;
CTrade         trade;
//--- Declare the indicator variables and handles
double         lot;
ulong          magic_number;
uint           stoploss;
uint           takeprofit;
uint          SLippage;
int            InpInd_Handle1,InpInd_Handle2;
double         avr_speed[],cam_up[],cam_dn[];
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Initial checks
   if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
     {
      Print(InpEaComment,": Trade is not allowed!");
      return(INIT_FAILED);
     }
   if(!TerminalInfoInteger(TERMINAL_CONNECTED))
     {
      Print(InpEaComment,": No Connection!");
      return(INIT_FAILED);
     }
//--- Get the Average Speed indicator handle
   InpInd_Handle1=iCustom(Symbol(),InpInd_Timeframe,"Speed Price\\average_speed",
                          InpBars,
                          InpPrice
                          );
   if(InpInd_Handle1==INVALID_HANDLE)
     {
      Print(InpEaComment,": Failed to get average_speed handle");
      Print("Handle = ",InpInd_Handle1,"  error = ",GetLastError());
      return(INIT_FAILED);
     }
//--- Get the CAM indicator handle
   InpInd_Handle2=iCustom(Symbol(),InpInd_Timeframe,"Speed Price\\CAM",
                          InpPeriodADX,
                          InpPeriodFast,
                          InpPeriodSlow
                          );
   if(InpInd_Handle2==INVALID_HANDLE)
     {
      Print(InpEaComment,": Failed to get average_speed handle");
      Print("Handle = ",InpInd_Handle2,"  error = ",GetLastError());
      return(INIT_FAILED);
     }
//---
   ArrayInitialize(avr_speed,0.0);
   ArrayInitialize(cam_up,0.0);
   ArrayInitialize(cam_dn,0.0);
   ArraySetAsSeries(avr_speed,true);
   ArraySetAsSeries(cam_up,true);
   ArraySetAsSeries(cam_dn,true);
//--- setting trade parameters
   lot=NormalizeLot(Symbol(),fmax(InpLot,MinimumLots(Symbol())));
   magic_number=InpMagicNum;
   stoploss=InpStopLoss;
   takeprofit=InpTakeProfit;
   slippage=InpSlippage;
//--- 
   trade.SetDeviationInPoints(slippage);
   trade.SetExpertMagicNumber(magic_number);
   trade.SetTypeFillingBySymbol(Symbol());
   trade.SetMarginMode();
   trade.LogLevel(LOG_LEVEL_NO);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   if(!MQLInfoInteger(MQL_TESTER))
      engine.OnTimer();
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- If working in the tester
   if(MQLInfoInteger(MQL_TESTER))
      engine.OnTimer();

   if(!IsOpenedByMagic(InpMagicNum))
     {
      //--- Get data for calculation
      if(!GetIndValue())
         return;
      //---
      if(BuySignal())
        {
         //--- Get correct StopLoss and TakeProfit prices relative to StopLevel
         doubleSL=CorrectStopLoss(Symbol(),ORDER_TYPE_BUY,0,stoploss);
         doubleTP=CorrectTakeProfit(Symbol(),ORDER_TYPE_BUY,0,takeprofit);
         //--- Open Buy position
         trade.Buy(lot,Symbol(),0,sl,tp);
        }
      else if(SellSignal())
        {
         //--- Get correct StopLoss and TakeProfit prices relative to StopLevel
         doubleSL=CorrectStopLoss(Symbol(),ORDER_TYPE_SELL,0,stoploss);
         doubleTP=CorrectTakeProfit(Symbol(),ORDER_TYPE_SELL,0,takeprofit);
         //--- Open Sell position
         trade.Sell(lot,Symbol(),0,sl,tp);
        }
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool BuySignal()
  {
   return(avr_speed[0]>=InpTrendLev && cam_up[0]!=EMPTY_VALUE)?true:false;
  }
//+------------------------------------------------------------------+
bool SellSignal()
  {
   return(avr_speed[0]>=InpTrendLev && cam_dn[0]!=EMPTY_VALUE)?true:false;
  }
//+------------------------------------------------------------------+
//| Get the current indicator values                                 |
//+------------------------------------------------------------------+
bool GetIndValue()
  {
   return(CopyBuffer(InpInd_Handle2,0,0,1,cam_up)<1 ||
          CopyBuffer(InpInd_Handle2,1,0,1,cam_dn)<1 || 
          CopyBuffer(InpInd_Handle1,0,0,1,avr_speed)<1
          )?false:true;
  }
//+------------------------------------------------------------------+
//| Check for open positions with a magic number                     |
//+------------------------------------------------------------------+
bool IsOpenedByMagic(int MagicNumber)
  {
   int pos=0;
   uint total=PositionsTotal();
//---
   for(uint i=0; i<total; i++)
     {
      if(SelectByIndex(i))
         if(PositionGetInteger(POSITION_MAGIC)==MagicNumber)
            pos++;
     }
   return((pos>0)?true:false);
  }
//+------------------------------------------------------------------+
//| Select a position on the index                                   |
//+------------------------------------------------------------------+
bool SelectByIndex(const int index)
  {
   ENUM_ACCOUNT_MARGIN_MODE margin_mode=(ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE);
//---
   if(margin_mode==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING)
     {
      ulong ticket=PositionGetTicket(index);
      if(ticket==0)
         return(false);
     }
   else
     {
      string name=PositionGetSymbol(index);
      if(name=="")
         return(false);
     }
//---
   return(true);
  }
//+------------------------------------------------------------------+

トレード戦略2

プライスインパルスEAのアイデアは、価格速度を測定する第2の方法に基づいてトレード戦略を実装するために使用します。 その主なポイントは、そこに費やされたティックの数を考慮して、価格が特定のポイント数に移動したときにトレードポジションを開きます。 

パラメータ 詳細
時間枠 任意 
買い条件 特定の数のティックに渡された価格ポイントの数。
売り条件 特定の数のティックに渡された価格ポイントの数。
決済条件   テイクプロフィット/ストップロス

戦略の実装は、以下のリストに記載されています。 ご覧のとおり、この設定には価格速度の推定を担当する 2 つのパラメータがあります。

//+------------------------------------------------------------------+
//| EA inputs                                                        |
//+------------------------------------------------------------------+
input string               InpEaComment         =  "Strategy #2"; // EA Comment
input int                  InpMagicNum          =  1111;          // Magic number
input double               InpLots              =  0.1;           // Lots
input uint                 InpStopLoss          =  400;           // StopLoss in points
input uint                 InpTakeProfit        =  500;           // TakeProfit in points
input ENUM_COPY_TICKS      tick_flags           =  TICKS_INFO;    // Ticks resulting from Bid and/or Ask changes
input int                  InpPoints            =  15;            // The price should move NNN points
input uchar                InpTicks             =  15;            // For XXX ticks

//--- arrays for accepting ticks
MqlTick        tick_array_curr[];            // ticks array obtained on the current tick
MqlTick        tick_array_prev[];            // ticks array obtained on the previous tick
ulong          tick_from=0;                  // if tick_from=0, the last tick_count ticks are given
uint           tick_count=15;                // number of ticks that should be obtained 
//---
double         ExtStopLoss=0.0;
double         ExtTakeProfit=0.0;
double         ExtPoints=0.0;
bool           first_start=false;
long           last_trade_time=0;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   if(!m_symbol.Name(Symbol()))              // sets symbol name
      return(INIT_FAILED);

   tick_count+=InpTicks;                     // request "tick_count" + "for XXX ticks"
   ExtStopLoss=InpStopLoss*Point();
   ExtTakeProfit=InpTakeProfit*Point();
   ExtPoints=InpPoints*Point();
   first_start=false;
//--- request ticks (first filling)
   int copied=CopyTicks(Symbol(),tick_array_curr,tick_flags,tick_from,tick_count);
   if(copied!=tick_count)
      first_start=false;
   else
     {
      first_start=true;
      ArrayCopy(tick_array_prev,tick_array_curr);
     }
   m_trade.SetExpertMagicNumber(InpMagicNum);
   m_trade.SetTypeFillingBySymbol(Symbol());
   m_trade.SetMarginMode();
   m_trade.LogLevel(LOG_LEVEL_NO);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- check for the first start
   int copied=-1;
   if(!first_start)
     {
      copied=CopyTicks(Symbol(),tick_array_curr,tick_flags,tick_from,tick_count);
      if(copied!=tick_count)
         first_start=false;
      else
        {
         first_start=true;
         ArrayCopy(tick_array_prev,tick_array_curr);
        }
     }
//--- request ticks
   copied=CopyTicks(Symbol(),tick_array_curr,tick_flags,tick_from,tick_count);
   if(copied!=tick_count)
      return;
   int index_new=-1;
   long last_time_msc=tick_array_prev[tick_count-1].time_msc;
   for(int i=(int)tick_count-1;i>=0;i--)
     {
      if(last_time_msc==tick_array_curr[i].time_msc)
        {
         index_new=i;
         break;
        }
     }
//---
   if(index_new!=-1 && !IsOpenedByMagic(InpMagicNum))
     {
      int shift=(int)tick_count-1-index_new-InpTicks;   // shift in the current ticks array
      shift=(shift<0)?0:shift;
      if(tick_array_curr[tick_count-1].ask-tick_array_curr[shift].ask>ExtPoints)
        {
         //--- open BUY
         doubleSL=(InpStopLoss==0)?0.0:tick_array_curr[tick_count-1].ask-ExtStopLoss;
         doubleTP=(InpTakeProfit==0)?0.0:tick_array_curr[tick_count-1].ask+ExtTakeProfit;
         m_trade.Buy(InpLots,m_symbol.Name(),tick_array_curr[tick_count-1].ask,
                     m_symbol.NormalizePrice(sl),
                     m_symbol.NormalizePrice(tp));
         last_trade_time=tick_array_curr[tick_count-1].time_msc;
        }
      else if(tick_array_curr[shift].bid-tick_array_curr[tick_count-1].bid>ExtPoints)
        {
         //--- open SELL
         doubleSL=(InpStopLoss==0)?0.0:tick_array_curr[tick_count-1].bid-ExtStopLoss;
         doubleTP=(InpTakeProfit==0)?0.0:tick_array_curr[tick_count-1].bid+ExtTakeProfit;
         m_trade.Sell(InpLots,m_symbol.Name(),tick_array_curr[tick_count-1].bid,
                      m_symbol.NormalizePrice(sl),
                      m_symbol.NormalizePrice(tp));
         last_trade_time=tick_array_curr[tick_count-1].time_msc;
        }
     }
   ArrayCopy(tick_array_prev,tick_array_curr);
//---
  }
//+------------------------------------------------------------------+
//| Check for open positions with the magic number                   |
//+------------------------------------------------------------------+
bool IsOpenedByMagic(int MagicNumber)
  {
   int pos=0;
   uint total=PositionsTotal();
//---
   for(uint i=0; i<total; i++)
     {
      if(SelectByIndex(i))
         if(PositionGetInteger(POSITION_MAGIC)==MagicNumber)
            pos++;
     }
   return((pos>0)?true:false);
  }
//+------------------------------------------------------------------+
//| Select a position on the index                                   |
//+------------------------------------------------------------------+
bool SelectByIndex(const int index)
  {
   ENUM_ACCOUNT_MARGIN_MODE margin_mode=(ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE);
//---
   if(margin_mode==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING)
     {
      ulong ticket=PositionGetTicket(index);
      if(ticket==0)
         return(false);
     }
   else
     {
      string name=PositionGetSymbol(index);
      if(name=="")
         return(false);
     }
//---
   return(true);
  }
//+------------------------------------------------------------------+

トレーディング戦略 3

間接的に価格速度を測定するトレード戦略を作成するには、トレンドインジケータと可能なシグナルを確認するフィルタを選択する必要があります。 今回の目的を考慮して、トレンドインジケータのトレンド方向と力を選択し、HMAカラーをフィルタとして選択しました。 図7は、インプットシグナルの売買を表示します。

図7. トレード戦略のエントリー条件

パラメータ 詳細
適用されたインジケータ Trend direction and force
適用されたインジケータ HMA カラー
時間枠 M30 以上
買い条件 「トレンド方向と高速」値が閾値よりも高く(線は青)、HMAが上向きに移動して青色に変わる。
売り条件 「トレンド方向と高速」値が閾値よりも低く(線は赤)、HMAが下方に移動して赤に変わる。
決済条件   テイクプロフィット/ストップロス


価格速度測定方法のテスト

選択した 3 つの戦略をテストするには、テストする条件を定義する必要があります。 

  • 間隔: Last year . (この執筆時点では、01.01.2019 - 26.05.2019です)
  • シンボル: EURUSD .
  • トレードモード: 遅延なし ( 高頻度トレード戦略ではありませんので、遅延の影響は小さいでしょう) 
  • テスト: М1 OHLC (実際のティックの事前テストはほぼ同じ結果を示しています). 
  • 初期資産: 1000 USD.
  • レバレッジ:  1:500.
  • サーバー:MetaQuotes-Demo
  • Quotes: 5-digit.

テストの目的は、ヒストリーに戦略を適合させるのではなく、価格速度を計算し、処理するための様々なアプローチの全体的なトレンドと効率を明らかにすることです。 したがって、レポートパラメータを使用した最良の最適化結果とその推定は、各トレード戦略に対して提供されます。 

トレード戦略 1.

標準的な価格速度の変化に基づいて最初の戦略をテストした後、特定の結果を受け取りました。 上位 20 位は以下の通りです。

図8. トレーディング戦略1 20ベスト最適化結果

結果から、これらのテスト条件下で、今回のトレード戦略は、小さなTPとSL値のとき、小さな時間枠で最良の結果を示していると結論付けることができます。 言い換えれば、検出されたシグナルの移動ポテンシャルは小さい。 同時に、シャープレシオ(トレード結果の推定方法とレードの数学の記事に関する詳細はこちら )は低く、有望な兆候ではありません。 次に、テスターで最良の結果を出し、次のレポートを受け取りました。


図9. トレード戦略1最良の最適化結果をテストした結果

0.1の一定ロットを使用すると、成長はほぼ100%ですが、シャープレシオはわずか0.33です。Zスコアは-0.16であり、トレードの一貫性の欠如とランダム因子の影響を示します。 

トレード戦略 2.

次の戦略をテストするには、戦略関数により 1 つのテスト条件を変更する必要があります。

  • テスト: M1 OHLC (実際のティックの事前テストはほぼ同じ結果を示しています) を "実際のティックに基づくすべてのティック"に置き換えます。

戦略の上位 20 の最適化オプションは次のとおりです。

図10. トレーディング戦略2 20ベスト最適化結果

平均して、シャープレシオは最初の戦略と比較してここで高く、最良の結果は、ティックの最小数内の適度な数のポイントで得られます。 このシステムはまた、トレードの少数によって示されているように選択的であることが判明しました. 最適な最適化結果をテストし、レポートを参照してみましょう。


図11. トレード戦略2の最良の最適化結果をテストした結果

30%を超える利益は10トレード以内にしか到達していないため、シャープレシオはここでより良く見えます。 

トレード戦略3.

この戦略では、初期のテスト条件に戻ります。 ここでは、間接的に価格の動きとその速度を決定するインジケータを使用してトレードをチェックします。

また、現在の戦略を最適化するための最良のオプションも参照してください。

図12. トレーディング戦略3 20ベスト最適化結果

結果のほとんどは似ています。 これは、直近の 2 つの最適化パラメータが最終結果に大きな影響を与えないことを示唆します。 同時に、平均シャープレシオは約0.2であり、それほど印象的ではありません。 最良の最適化結果は、もちろん、一般的なオーダーから外れていますが、以前のトレード戦略のようにバックテストを行うつもりです。


図13. トレーディング戦略3最良の最適化結果をテストした結果

資産のほぼ100%の成長とシャープレシオ(現在の利益レベルに達するために52のトレードを要したという事実によって注目されるが、最も近い結果はほぼ2倍少ない)それにも関わらず、Zスコアは間の負の相関関係を示しています。 収益性の高いトレードは収益性の低いトレードの後に続き、その逆もまたあるということを意味します。 

要約

価格速度を測定する3つのアプローチをテストし、最良のバックテストやその他の最適化の結果を調べた後、最初の方法の最良の最適化結果は一貫性を欠いていることが明らかになりました。 残りの2つの方法は、シャープレシオが高く、トレード間の負の相関がより良い結果を示しました。 もちろん、テスト戦略は、価格速度測定方法の全体の多様性を網羅していませんが、この記事では、トレード方法を理解する最も明白で最も簡単なものいくつかを説明しました。

結論

以下に添付されているアーカイブには、適切なフォルダに配置された記述されたすべてのファイルがあります。 正しく動作させるには、MQL5 フォルダをターミナルのルート ディレクトリに保存する必要があります。 MQL5フォルダが配置されているターミナルルートディレクトリを開くには、MetaTrader5ターミナルでCtrl+Shift+Dキーの組み合わせを押すか、下の図14に示すようにコンテキストメニューを使用します。


図14. MetaTrader5 ターミナル ルートで MQL5 フォルダを開く

この記事で使用するプログラム:

#
 名前
種類
詳細
1
Strategy_1.mq5 EA  トレード戦略1に基づくEA
2 Strategy_2.mq5 EA  トレード戦略2に基づくEA
3 Strategy_3.mq5 EA   トレード戦略3に基づくEA
4 Engine.mqh ライブラリ  トレード関数のライブラリ
 5 Average Speed  インジケーター   トレード戦略1で使用
 6 CAM  インジケーター    トレード戦略1で使用
 7 Trend direction and force  インジケーター    トレード戦略3で使用
 8 HMA_color  インジケーター   トレード戦略3で使用


MetaQuotes Software Corp.によりロシア語から翻訳された
元の記事: https://www.mql5.com/ru/articles/6947

添付されたファイル |
MQL5.zip (734.69 KB)
MetaTraderプログラムを簡単かつ迅速に開発するためのライブラリ(第5部): ネッティング勘定イベント MetaTraderプログラムを簡単かつ迅速に開発するためのライブラリ(第5部): ネッティング勘定イベント

前の記事では、MetaTrader 5とMetaTrader 4プラットフォーム用のプログラムの開発を単純化するための大規模なクロスプラットフォームライブラリの作成を始めました。連載第5回では、取引イベントクラスとイベントコレクションを作成し、イベントをEngineライブラリの基本オブジェクトとコントロールプログラムチャートに送信しました。今回は、ライブラリをネッティング勘定で動作させます。

MetaTraderプログラムを簡単かつ迅速に開発するためのライブラリ(第5部): 取引イベントのクラスとコレクション、プログラムへのイベント送信 MetaTraderプログラムを簡単かつ迅速に開発するためのライブラリ(第5部): 取引イベントのクラスとコレクション、プログラムへのイベント送信

前の記事では、MetaTrader 5とMetaTrader 4プラットフォーム用のプログラムの開発を単純化するための大規模なクロスプラットフォームライブラリの作成を始めました。第4部では、口座の取引イベントの追跡をテストしました。本稿では、取引イベントクラスを開発してイベントコレクションに配置します。そこからは、これらはエンジンライブラリの基本オブジェクトとコントロールプログラムチャートに送信されます。

MetaTraderプログラムを簡単かつ迅速に開発するためのライブラリ(第7部): StopLimit注文発動イベント、注文およびポジション変更イベント機能の準備 MetaTraderプログラムを簡単かつ迅速に開発するためのライブラリ(第7部): StopLimit注文発動イベント、注文およびポジション変更イベント機能の準備

前の記事では、MetaTrader 5とMetaTrader 4プラットフォーム用のプログラムの開発を単純化するための大規模なクロスプラットフォームライブラリの作成を始めました。第6部分では、ネッティング勘定のポジションを扱うようにライブラリを訓練しました。今回は、StopLimit注文の発動の追跡を実装し、注文とポジションの変更イベントを追跡する関数を準備します。

ローソク足分析技術の研究(第4部): パターンアナライザーの更新と追加 ローソク足分析技術の研究(第4部): パターンアナライザーの更新と追加

本稿では、パターンアナライザーアプリケーションの新しいバージョンについて説明します。このバージョンでは、バグ修正と新機能、そして改訂されたユーザーインターフェイスが提供されています。新しいバージョンを開発するときに、前の記事からのコメントと提案が考慮されました。結果として得られたアプリケーションは、この記事で説明されています。