リニアなトレーディングシステムを指数に高める

24 11月 2015, 15:53
Jordi Bassaganas
0
366

はじめに

本稿では MQL5 プログラマーの中級者にリニアなトレーディングシステム(固定ロット)からいわゆる指数の技術を簡単に実装することでより収益を上げる方法をお伝えします。ここでは個人が負うリスクに応じてマーケットに置かれたサイズまたはポジション数を適応する資金管理モデルを参照するため累乗法の一般的な用語が使用されます。これは結果として生じる資金曲線の成長が幾何学的または指数関数で放物線の形を取ります。『リニア』という語もまた数学とプログラムの中間といったコンテキストで使用されます。特にラルフ・ビンス氏によって開発された実用的な「固定比率」のポジションサイジングの MQL5 のバリアントを実装します。

図1 数学的放物線


図1 数学的放物線

「資金管理モデル」を概説し、ラルフ・ビンス氏の「固定比率」ポジションサイジングのバリアントを実装する方法を確認します。準備はいいですか?みなさんのトレーディング戦略からより多くを手にする機会を見逃さないでください!


1. 資金管理モデルとは?

簡単に言えば「資金管理モデル」は概念的枠組みでその下でポジションサイズ、ストップロスの使用、マージン計算、トレードコストに関する判断をします。そこには数多くの「資金管理モデル」があります!お望みならそれら古典的な枠組みに関する知識を深めるため「固定ロット」、「固定小数」、「固定比率」、「ケリー基準」、「費用対効果」でグーグル検索することができます。申し上げたとおり、本稿では「固定比率」のバリアントしか取り上げません。


1.2. 固定比率

この資金管理モデルの背後にある考えはそれに関連する推定リスクに応じたサイジング処理です。リスクは各トレードにおいてネットで同じ比率です。 

固定比率のポジションサイジングにおける契約数に対する式は以下のようなものです。



N = f ×資金 / トレードリスク

N は契約数、f は固定比率(0と1の間の数)、資金はアカウント資金の現在値、トレードリスクは契約数が計算される契約ごとのトレードのリスクです。Michael R. Bryant 著の記事Fixed Fractional Position Sizing を読んで本件に関してよりよく学習してください。

固定比率モデルの興味深いプロパティは処理サイズがアカウントのネットバランスに比例しているため、理論的には資本をすべて失うのは不可能であるということです。破滅の危険性はゼロなのです。一方、リスク資本の割合が低いため一連の処理の勝敗は利益曲線にたいした影響を与えません。


2. トレーディングシステムへの固定比率の追加


2.1. リニアなトレーディングシステムを取る

低リスク指数パワーを経験するにはまずリニアトレーディングシステムが必要です。このシステムはいわばパワー基盤の役割を果たします。リニアシステムによって特定期間に勝者と証明され、その資金曲線が直線のように見えるトレーディングシステムを意味しています。たとえば、HawaiianTsunamiSurferはコードベースで利用可能ないわゆるリニアトレーディングシステムです。その資金曲線は2012 年1月~ 2012年3月に直線に見えます。

図2 HawaiianTsunamiSurferの資金曲線(2012 年1月~ 2012年3月)

図2 HawaiianTsunamiSurferの資金曲線(2012 年1月~ 2012年3月)

本稿の狙いはリニアトレーディングシステムを一から作成することではなくみなさんがご自身のシステムからより利益をあげるのに必要なツールを提供することです。そこで、ここからはみなさんがすでにオブジェクト指向パラダイムの下このようなトレーディングシステムを開発済みであるとしてお話します。この場合、以下で説明する OO ピースを追加する必要があります。

2.2. みなさんのシステムをパワーに高めるMQL5 のコアクラス、CEvolution

われわれのEAをコード化するためふたたびオブジェクト指向のアプローチを行います。まず記事Another MQL5 OOP class および Building an Automatic News Trader を読んでこの OO 方法で作業するための技術的基礎を入手いただくことをお薦めします。すでにこれが済んでいればこれら記事で語られている設計は CEvolutionと呼ばれるひじょうに重要なエレメントを採り入れていることを忘れないでください。これによりわれわれは既定時刻におけるロボットの状態、行われた処理履歴など重要な一時的情報を追跡することができるのです。

ここで資金管理に必要なロジックを CEvolution 内にコード化します。リスクのある固定比率は資金に比例し、そこでだれもがそれは定数ではなく変数であることに同意するので、このロジックはCEvolution内でコード化される必要があります。または簡単に言うと資金曲線の傾きは時間とともに進化するため、このすべてが実装されるべき CEvolution にあります。これはわれわれのオブジェクトプログラミングの抽象的な考え方です。それはみなさんが以下の OO クラスをご自身のオブジェクト指向スタイルのトレーディングシステムと統合する練習に残しておきます。

クラス CEvolution.mqh

//+------------------------------------------------------------------+
//|                                                   CEvolution.mqh |
//|                               Copyright © 2013, Jordi Bassagañas |
//+------------------------------------------------------------------+
#include <Mine\Enums.mqh>
//+------------------------------------------------------------------+
//| CEvolution Class                                                 |
//+------------------------------------------------------------------+
class CEvolution
  {
protected:
   ENUM_STATUS_EA                   m_status;            // The current EA's status
   ENUM_EXP_EQUITY_CURVE_LEVEL      m_expEquityLevel;    // The current exponential equity level
   double                           m_originalEquity;    // The original equity value
   double                           m_lotSize;           // The current lot size

public:
   //--- Constructor and destructor methods
                                    CEvolution(ENUM_STATUS_EA status,ENUM_EXP_EQUITY_CURVE_LEVEL exp_equity_level);
                                    ~CEvolution(void);
   //--- Getter methods
   ENUM_STATUS_EA                   GetStatus(void);
   ENUM_EXP_EQUITY_CURVE_LEVEL      GetExpEquityLevel(void);
   double                           GetOriginalEquity(void);
   double                           GetLotSize(void);
   //--- Setter methods
   void                             SetStatus(ENUM_STATUS_EA status);
   void                             SetExpEquityLevel(ENUM_EXP_EQUITY_CURVE_LEVEL exp_equity_level);
   void                             SetOriginalEquity(double equity);
   void                             SetLotSize(double size);
   //--- CEvolution specific methods
   double                           CalcEquityGrowth(double currentEquity);
   void                             RefreshExpEquityLevel(double currentEquity);
   void                             RefreshLotSize();
  };
//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CEvolution::CEvolution(ENUM_STATUS_EA status,ENUM_EXP_EQUITY_CURVE_LEVEL exp_equity_level)
  {
   m_status=status;
   m_expEquityLevel=exp_equity_level;
   RefreshLotSize();
   m_originalEquity=AccountInfoDouble(ACCOUNT_EQUITY);
  }
//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+
CEvolution::~CEvolution(void)
  {
  }
//+------------------------------------------------------------------+
//| GetStatus                                                        |
//+------------------------------------------------------------------+
ENUM_STATUS_EA CEvolution::GetStatus(void)
  {
   return m_status;
  }
//+------------------------------------------------------------------+
//| GetExpEquityLevel                                                |
//+------------------------------------------------------------------+
ENUM_EXP_EQUITY_CURVE_LEVEL CEvolution::GetExpEquityLevel(void)
  {
   return m_expEquityLevel;
  }
//+------------------------------------------------------------------+
//| GetEquity                                                        |
//+------------------------------------------------------------------+
double CEvolution::GetOriginalEquity(void)
  {
   return m_originalEquity;
  }
//+------------------------------------------------------------------+
//| GetLotSize                                                       |
//+------------------------------------------------------------------+
double CEvolution::GetLotSize(void)
  {
   return m_lotSize;
  }
//+------------------------------------------------------------------+
//| SetStatus                                                        |
//+------------------------------------------------------------------+
void CEvolution::SetStatus(ENUM_STATUS_EA status)
  {
   m_status=status;
  }
//+------------------------------------------------------------------+
//| SetExpEquityLevel                                                |
//+------------------------------------------------------------------+
void CEvolution::SetExpEquityLevel(ENUM_EXP_EQUITY_CURVE_LEVEL exp_equity_level)
  {
   m_expEquityLevel=exp_equity_level;
  }
//+------------------------------------------------------------------+
//| SetEquity                                                        |
//+------------------------------------------------------------------+
void CEvolution::SetOriginalEquity(double equity)
  {
   m_originalEquity=equity;
  }
//+------------------------------------------------------------------+
//| SetLotSize                                                       |
//+------------------------------------------------------------------+
void CEvolution::SetLotSize(double lot_size)
  {
   m_lotSize=lot_size;
  }
//+------------------------------------------------------------------+
//| CalcEquityGrowth                                                 |
//+------------------------------------------------------------------+
double CEvolution::CalcEquityGrowth(double currentEquity)
  {
   return NormalizeDouble(currentEquity * 100 / m_originalEquity - 100,2);
  }
//+------------------------------------------------------------------+
//| RefreshExpEquityLevel                                            |
//+------------------------------------------------------------------+
void CEvolution::RefreshExpEquityLevel(double currentEquity)
  {
   double growth = CalcEquityGrowth(currentEquity);
   //--- is the current equity less than 10% of the original amount?
   if(growth <= 10)
   {
      SetExpEquityLevel(LEVEL_ONE);
   }
   //--- is the current equity more than 10% of the original amount and less than 20%?
   else if(growth > 10 && growth <= 20)
   {
      SetExpEquityLevel(LEVEL_TWO);
   }
   //--- is the current equity more than 20% of the original amount and less than 30%?
   else if(growth > 20 && growth <= 30)
   {
      SetExpEquityLevel(LEVEL_THREE);
   }
   //--- is the current equity more than 30% of the original amount and less than 40%?
   else if(growth > 30 && growth <= 40)
   {
      SetExpEquityLevel(LEVEL_FOUR);
   }
   //--- is the current equity more than 40% of the original amount and less than 50%?
   else if(growth > 40 && growth <= 50)
   {
      SetExpEquityLevel(LEVEL_FIVE);
   }
   //--- is the current equity more than 50% of the original amount and less than 60%?
   else if(growth > 50 && growth <= 60)
   {
      SetExpEquityLevel(LEVEL_SEVEN);
   }
   //--- is the current equity more than 60% of the original amount and less than 70%?   
   else if(growth > 60 && growth <= 70)
   {
      SetExpEquityLevel(LEVEL_EIGHT);
   }
   //--- is the current equity more than 70% of the original amount and less than 80%?   
   else if(growth > 70 && growth <= 80)
   {
      SetExpEquityLevel(LEVEL_NINE);
   }
   //--- is the current equity more than 90% of the original amount?
   else if(growth > 90)
   {
      SetExpEquityLevel(LEVEL_TEN);
   }
  }
//+------------------------------------------------------------------+
//| RefreshLotSize                                                   |
//+------------------------------------------------------------------+
void CEvolution::RefreshLotSize()
  {
   switch(m_expEquityLevel)
   {
      case LEVEL_ONE:
         SetLotSize(0.01);
         break;
         
      case LEVEL_TWO:
         SetLotSize(0.02);
         break;
         
      case LEVEL_THREE:
         SetLotSize(0.03);
         break;
         
      case LEVEL_FOUR:
         SetLotSize(0.04);
         break;
         
      case LEVEL_FIVE:
         SetLotSize(0.05);
         break;
         
      case LEVEL_SIX:
         SetLotSize(0.06);
         break;
         
      case LEVEL_SEVEN:
         SetLotSize(0.07);
         break;

      case LEVEL_EIGHT:
         SetLotSize(0.08);
         break;
         
      case LEVEL_NINE:
         SetLotSize(0.09);
         break;
         
      case LEVEL_TEN:
         SetLotSize(0.1);
         break;
   }
  }
//+------------------------------------------------------------------+

ここでこのクラスの需要箇所についてコメントします。 

Expert Advisor が作成されるとき、元の資金曲線の値は m_originalEquityに格納されます。

//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CEvolution::CEvolution(ENUM_STATUS_EA status,ENUM_EXP_EQUITY_CURVE_LEVEL exp_equity_level)
  {
   m_status=status;
   m_expEquityLevel=exp_equity_level;
   RefreshLotSize();
   m_originalEquity=AccountInfoDouble(ACCOUNT_EQUITY);
  }

メソッド CEvolution::CalcEquityGrowth は資金曲線の成長を計算し、つねにそのもとの値に関連しています。

//+------------------------------------------------------------------+
//| CalcEquityGrowth                                                 |
//+------------------------------------------------------------------+
double CEvolution::CalcEquityGrowth(double currentEquity)
  {
   return NormalizeDouble(currentEquity * 100 / m_originalEquity - 100,2);
  }

最後に CEvolution::RefreshExpEquityLevel はティック毎に資金レベルをリフレッシュし(それがどのように絶対的に資本成長に依存するかを観察します)CEvolution::RefreshLotSize はティック毎にロットサイズをリフレッシュします。これはみなさんの EAの OnTick メソッドで情報を以下のようにリフレッシュすることになっているためです。

GetEvolution().RefreshExpEquityLevel(AccountInfoDouble(ACCOUNT_EQUITY));
GetEvolution().RefreshLotSize();

ところでこのソリューションは次のカスタム MQL5 列挙を必要とします。

//+------------------------------------------------------------------+
//| Exponential equity curve level enumeration                       |
//+------------------------------------------------------------------+
enum ENUM_EXP_EQUITY_CURVE_LEVEL
  {
   LEVEL_ONE,
   LEVEL_TWO,
   LEVEL_THREE,
   LEVEL_FOUR,
   LEVEL_FIVE,
   LEVEL_SIX,
   LEVEL_SEVEN,
   LEVEL_EIGHT,
   LEVEL_NINE,
   LEVEL_TEN
  };
この自走は固定比率のバリアントであるとしています。それが実際いくらかの特異性を持つためです。たとえば、資金曲線はいわゆるレベル10に到達するまで指数関数的に成長し、その後システムはリニアになります。それでもなお CEvolution は資金曲線に比例してポジションサイズが絶えず増加するという基本的考えを保ちます。

2.3. 個人の固定比率判断

上述すべてでみなさんあすでにお手持ちのロボットの現状を基にして資金管理の判断を行うことができます。

みなさんの EAの OnTick メソッドのどこかで

switch(GetEvolution().GetStatus())
     {
      case BUY:

         tp = ask + m_takeProfit * _Point;
         sl = bid - m_stopLoss * _Point;

         GetTrade().PositionOpen(GetBrain().GetSymbol(),ORDER_TYPE_BUY,m_evolution.GetLotSize(),ask,sl,tp);
         
         break;

      case SELL:

         sl = ask + m_takeProfit * _Point;
         tp = bid - m_stopLoss * _Point;

         GetTrade().PositionOpen(GetBrain().GetSymbol(),ORDER_TYPE_SELL,m_evolution.GetLotSize(),bid,sl,tp);
         
         break;

      case DO_NOTHING:

         // Nothing...

         break;
     }

私は新しい指数化システムの名前を ExponentialHawaiianと付けなおしました。


3. 指数化システムのバックテスト

上で説明した OO ロジックをご自身のシステムに追加したら検証の実行を忘れないでください。私はここで HawaiianTsunamiSurferの固定比率バリアントである ExponentialHawaiianをバックテストしています。

図3 ExponentialHawaiianの資金曲線(2012 年1月~ 2012年3月)

図3 ExponentialHawaiianの資金曲線(2012 年1月~ 2012年3月)

基盤となるシステムがリニアなまま、上記の曲線は指数的なままです。この条件が真でなくなると、システムは理論的破滅のリスクを伴い不安定になります。


おわりに

今日われわれは固定ロットの資金管理モデルを実装しているリニアなトレーディングシステムを累乗のパワーに引き上げることでそこからよりおおくの利益をあげる方法を学習しました。

古典的な資金管理モデルをいくつか(「固定ロット」、「固定小数」、「固定比率」、「ケリー基準」、「費用対効果」)紹介することから始め、固定比率に着目することにしました。これは処理サイズがアカウントのネットバランスに比例して維持されるシンプルなモデルです。最後にある期間のリニアな結果を示すトレーディングシステムを取り入れ、固定比率のバリアントを MQL5 に実装し、MetaTraderのストラテジーテスタによって導かれた結果を示しました。

再度われわれの Expert Advisorsにはオブジェクト指向アプローチを取り入れました。まず記事 Another MQL5 OOP class および Building an Automatic News Trader を読み、この OO 方法で作業するための技術的基礎を入手することを強くお薦めします。

MetaQuotes Software Corp.により英語から翻訳された
元の記事: https://www.mql5.com/en/articles/734

添付されたファイル |
cevolution.mqh (8.35 KB)
テクニカルインディケータとデジタルフィルター テクニカルインディケータとデジタルフィルター

本稿ではデジタルフィルターとしてテクニカルインディケータを取り上げます。デジタルフィルターの処理原則と基本特性が説明されます。また、MetaTrader 5 ターミナルでフィルターカーネルを受け取る実用的な方法と記事 "Building a Spectrum Analyzer" で提案されている既製のスペクトル解析機能との統合について考察します。例として典型的デジタルフィルターのパルスとスペクトル特性を使用します。

MQL5 標準ライブラリの拡張とコードの再利用 MQL5 標準ライブラリの拡張とコードの再利用

MQL5 標準ライブラリによってみなさんの開発者としての生活は楽になります。しかしながらそれは世界中の開発者全員のすべてのニーズを実装するわけではありません。よってみなさんがカスタム的なものをもっと必要とするなら一歩先へすすんで拡張することができます。本稿は MetaQuotesの Zig-Zag テクニカルインディケータを標準ライブラリに統合する方法をご紹介します。私達はMetaQuotes の設計哲学により自分自身の目標を達成しようという気持ちになります。

有用なテクノロジーカクテルでYour MQL5 顧客を驚嘆させる! 有用なテクノロジーカクテルでYour MQL5 顧客を驚嘆させる!

MQL5 はプログラマーに関数の完全セットとオブジェクト指向API を提供します。それらのお陰でプログラマーは MetaTrader 環境内で願うことを行うことができるのです。ただ「ウェブテクノロジー」は今日ひじょに特殊なことをしてなにか違ったもので顧客を驚かせる必要があったり、ただ MT5 「標準ライブラリ」の特定箇所をマスターする十分な時間がないなんらかの状況で救助にきてくれる極端に多才なツールです。今回の例題によりご自身の開発時間管理の仕方と同時にすばらしいテクノロジーカクテルを作成する方法を実用例をご紹介します。

MQL5 ウィザード:任意の価格で指値注文をオープンすることを EA に教える方法 MQL5 ウィザード:任意の価格で指値注文をオープンすることを EA に教える方法

本稿は現在価格から任意の距離で指値注文を設定することができるようになる機能性の実装のためのトレードシグナルモジュールコードを変更するメソッドについてお話します。それは前回バーの価格クローズまたはオープンであり、あるいは移動平均の値の可能性があります。オプションは数多くあります。重要なことは指値注文に対して任意の始値を設定することができるということです。本稿は指値注文でトレードを行うトレーダーにとっては有用なものとなるでしょう。