【FX自動売買】EA入門 本格的にトレードを行うための関数を作る【MT4】

FX 自動売買(EA)

この記事は【EAの教科書シリーズ】の一部です。全記事は以下から確認できます。

これまでに別記事でEAにトレードを行わせるために必要な様々な関数を紹介してきました。本記事ではその中でも最も重要といっても過言でない実際にトレードを行わせるための関数を紹介していきます。

MT4をまだダウンロードしていない方はこちらのページでダウンロード方法を案内しているので、事前にMT4を用意しておいてください。

関数の概要

今回作成していく関数の名前はシンプルにTradeとします。戻り値はなく、引数にはint型のDirectionをとり、買い注文か売り注文かを指定するために使います。今回は0は買い注文、1は売り注文を表すことにします。

また今回作成するTradeには実践的なオプションがあり、ストップロスを設定するか、利確ポイントを設定するか、決済注文をリスクリワードレシオ(得られる収益と取らなければいけないリスクの割合)で指定するか、注文量を口座にある証拠金に対する割合で指定するかなどを設定できるようにします。

今回使用するグローバル変数

  • extern bool UseStopLoss:トレードにストップロスを設定する場合はtrueにします。デフォルト値はtrueにしています。
  • extern bool UseTakeProfit:トレードに利確ポイントを設定する場合はtrueにします。デフォルト値はtrueにしています。
     
  • extern bool UsePositionSizing:注文量を証拠金に対する割合で指定する場合はtrueにします。デフォルト値はtrueにしています。
  • extern bool UseRiskReward:リスクリワードレシオを使用して決済注文を行わせたい場合はtrueにします。デフォルト値はtrueにしています。
     
  • extern double RewardRatio:リスクリワードレシオを指定するための変数です。この値が2の場合は、利確ポイントまでのpipsが損切りポイントの2倍であることを意味します。つまり勝ちトレードで得られる収益が負けトレードで失う額の2倍になります。
     
  • extern int RiskPercent:口座にある証拠金の何%分の注文量を出すかを指定するための変数です。一回のトレードでとるリスクの大きさとも考えられます。1にした場合、一回の注文で証拠金の1%分のトレードが行われます。

関数のコード

void Trade(int Direction) //1
{
double SL; //2
double TP; //3
double Equity=AccountEquity(); //4
double RiskedAmount=Equity*RiskPercent*0.01; //5
double Lots=0; //6
   //買い注文の場合
   if(Direction==0) //7
      {
      if(UseStopLoss) //8
         {
         SL=Bid-StopLoss*pips;
         }
      else
         {
         SL=0;
         }
      if(UseTakeProfit) //9
         {
         if(UseRiskReward && UseStopLoss) //10
            {
            TP=StopLoss*pips*RewardRatio+Bid;
            }
         else
            {
            TP=Bid+TakeProfit*pips;
            }
         }
      else
         {
         TP=0;
         }
      if(UsePositionSizing && UseStopLoss) //11
         {
         Lots=(RiskedAmount/StopLoss)/10;
         }
      else
         {
         Lots=LotSize;
         }
      int res=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,NormalizeDouble(SL,4),NormalizeDouble(TP,4),NULL,0,0,clrNONE); //12
      }
   //売り注文の場合   
   if(Direction==1)
      {
      if(UseStopLoss) //8
         {
         SL=Ask+StopLoss*pips;
         }
      else
         {
         SL=0;
         }
      if(UseTakeProfit) //9
         {
         if(UseRiskReward && UseStopLoss) //10
            {
            TP=Ask-StopLoss*pips*RewardRatio;
            }
         else
            {
            TP=Ask-TakeProfit*pips;
            }
         }
      else
         {
         TP=0;
         }
      if(UsePositionSizing && UseStopLoss) //11
         {
         Lots=(RiskedAmount/StopLoss)/10;
         }
      else
         {
         Lots=LotSize;
         }
      int res=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,NormalizeDouble(SL,4),NormalizeDouble(TP,4),NULL,0,0,clrNONE); //12
      }
return;
}

上から順番に何をおこなっているのか解説していきます。

  1. まずは関数の宣言からです。戻り値はないので、voidとし、関数名Trade、引数は売りか買いかを示す(int Direction)です。使うときにはTrade(0)などのようにして呼び出します。
     
  2. ストップロスを表すための変数SLを宣言しています。最終的にOrderSend()関数で注文を出すときに使用します。ここでは何も代入しません。
     
  3. 利確ポイントを表すための変数TPを宣言しています。最終的にOrderSend()関数で注文を出すときに使用します。ここでは何も代入しません。
     
  4. 証拠金残高を表すための変数Equityを宣言しています。これには現在の口座にある証拠金残高がAccountEquity()関数によって代入されています。
     
  5. 一回のトレードでとるリスク量を表すための変数を宣言しています。グローバルエリアで宣言しているRiskPercent変数とそれを%に変換するために0.01と先程のEquity変数をかけた値が大ニュされています。
     
  6. 注文量を表すためのLots変数を宣言しています。初期値は0を代入しています。
    2~6で宣言した変数は全てTrade()関数内のローカル変数ですので、Trade()関数内のみで使用できます。
     
  7. 買い注文かを判別しています。買い注文である場合、すなわちTrade(0)で呼び出した場合はこのif文の中の処理が全て実行されます。
     
  8. ストップロスを設定するかを判別しています。UseStopLossがtrueである場合にはストップロスはBid – StopLoss * pipsになります。そうでない場合は0、すなわちストップロスが設定されません。
     
  9. 利確ポイントを設定するかを判別しています。
     
  10. 9で利確ポイントを設定する場合にはさらにリスクリワードレシオを使って利確ポイントを設定するかを判別しています。リスクリワードレシオはストップロスに対する見込み利益の割合なので、必然的にストップロスも使用している必要があります。そのためUseStopLossがtrueかも判定しています。
    もし両者ともtrueの場合、StopLoss変数をpips単位に変換した値にグローバルエリアで設定したRewardRatioをかけた値をBid(現在の売値)に足すことで、ストップロス x RewardRatio倍が利益になるように利確ポイントを設定します。
    リスクリワードレシオを使わない場合は利確ポイントはBid + TakeProfit * pipsになります。
     
  11. 注文量を指定するかをUsePositionSizingとUseStopLossで判定しています。どちらもtrueの場合、注文量(Lots)はRiskedAmountに設定された値とStopLossに設定された値をもとに算出した値に設定されます。
     
  12. 最後にここまでで設定された変数を利用してOrderSend()関数で注文を出しています。
     

グローバルエリアは以下のようになっています。

extern int TakeProfit=50;
extern int StopLoss=25;
extern double LotSize=0.01;

extern bool UseBreakEven=true;
extern int MoveToBreakEven=40;
extern int PipsProfitLock=20;

double pips;

extern bool UseTrailingStop=true;
extern int TrailTrigger=50;
extern int TrailAmount=50;
extern bool UseStopLoss=true;
extern bool UseTakeProfit=true;
extern bool UseRiskReward=true;
extern bool UsePositionSizing=true;
extern int RiskPercent=1;
extern int RewardRatio=2;

Trade()関数の使い方

この関数はエントリータイミングが来たタイミングで発注するための関数ですので、エントリータイミングを見極めるための関数と組み合わせて使用します。

エントリータイミングを見極める関数については以下をご覧ください。

プロフィール

プロフィール
コードラボJP

大学卒業後SEに就職、現在は退職しフリーランスとして活動中。
『初心者でも挫折せずに一人でプログラミングを学べる』をモットーに、コードラボJPを開設
お問い合わせ等はcodelabsjp@gmail.comまで

コードラボJPをフォローする
タイトルとURLをコピーしました