ZigZagEAにロット数調整や指値変更処理を組み込む(サンプルソース)

記事内に商品プロモーションを含む場合があります
スポンサーリンク

今回は、MT4のEAサンプルソース(FX用)を公開します。

トレードに使うテクニカル分析はZigZagで、どれだけPF(プロフィットファクター)を上げる事ができるかを追求したサンプルソースになります。

はじめに

私が公開しているZigZagのサンプルに以下の手法を入れました。

  • マーチンゲール
  • 指値・逆指値再設定

結果として直近4年間でプロフィットファクターは1.64、勝率も約83%、取引回数が1640と中々良い状態のEAに仕上がりました。

※ベースとなったZigZagサンプルEA(ナンピン版)の記事はこちら

EAの仕様

それでは、今回のソースコードのエントリー/決済/パラメータ設定についての仕様を説明します。

エントリータイミング

エントリー

高値/安値の切り上げでロングエントリー、高値/安値の切り下げでショートエントリーします。

ナンピンポイント

ナンピンするのは、デメリットが発生した場合。

最大ポジション数が4回までナンピンを行います。

今回の修正について

マーチンゲール

今回は何をしたのかと言うと、ナンピン時にロット数を増やしています。

ロット数を0.01に設定した場合、ナンピンとして2回目エントリー時は0.02、ナンピンとして3回目エントリー時は0.04、ナンピンとして4回目エントリー時は0.06という形にしました。

ロット数を0.02に設定した場合、ナンピンとして2回目エントリー時は0.04、ナンピンとして3回目エントリー時は0.08、ナンピンとして4回目エントリー時は0.12という形にしました。

4回目も倍にすると、ちょっと大きくなり過ぎかなとおもったので少しマイルドな感じにしました。マーチンゲール法とココモ法の間みたいな感じです。

指値、逆指値調整

あと4回目のナンピン時に変更注文をし、2回目ナンピンと3回目ナンピンの指値の位置を浅く設定しなおしています。
※4回目のナンピンともなると相当不利な状況になっているため

この修正を加える前と後の違いを実際のエントリーポイントで確認してみるとこんな感じです。

※こちらは修正前
※こちらが修正後

修正前は、ショートポジションが2つストップロスになっているのに対して修正後は、ストップロスが1つのみ(最初の一番ロット数が少ないもののみ)になっている事が分かると思います。

その他の仕様

EAの設定値は以下の通りです。

  1. E_Depth = 16 ⇒ ZigZagの「Depth」設定です。
  2. E_Deviation = 5 ⇒ ZigZagの「Deviation」設定です。
  3. E_Backstep = 3 ⇒ ZigZagの「Backstep」設定です。
  4. STOP_LOSS = 400 ⇒ 損切り幅です。(400で40pips)
  5. TP= 100 ⇒ 利確幅です。(100で10pips)
  6. A_SPREAD = 10 ⇒ 許容スプレッド幅です。(10で1pips)
  7. Lots = 0.01 ⇒ 初期ロット数です。

新しい足(バー)が出来た際に1度だけ処理を行います。※1時間足の場合だと1時間に1回処理する

ZigZagの設定値及び、エントリー時の指値、逆指値はパラメータ設定できます。

スポンサーリンク

EAレポート結果

※サンプルEAの作り上、始値のみの確認となっています

修正前のZigZagのEAと同じ期間でバックテストを行いました。プロフィットファクターの値が1.15から1.24に改善されています。特に2016年以降から現在についてはかなり調子のいい感じに仕上がりました。

2016年からの結果はこんな感じです。

プロフィットファクターは1.64で勝率も約83%、4年間で取引回数1640と中々良い状態です。

ダウンロード

上記のEAファイルになります。

“ZigMAX-EA” をダウンロード 15_ZIGMAX.ex4 – 3981 回のダウンロード – 19.92 KB

ソースコード

以下サンプルソースコードになります。
※丸々コピペでコンパイルできます

//+------------------------------------------------------------------+
//|                                             ZigZag_NanpinLot.mq4 |
//|                                    Copyright 2020, mef Software. |
//|                                             https://fx-prog.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, mef Software."
#property link      "https://fx-prog.com/"
#property version   "1.01"
          
input int E_Depth = 16;
input int E_Deviation = 5;
input int E_Backstep = 3;
       
input int STOP_LOSS = 400;
input int TP = 100;
input int A_SPREAD = 10;
  
input double Lots = 0.01;
  
       
double ZigTop[5];     //ジグザグの山保存用
double ZigBottom[5];  //ジグザグの谷保存用
int TopPoint;
int BottomPoint;
       
double maisuu=0.01;
datetime prevtime;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//---
              
//---
   return(INIT_SUCCEEDED);
  }
           
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
int start()
{
int orderPtn=0; //0:何もしない 1:買い 2:売り
int total=0;
           
double ea_order_stop_price=0,ea_order_good_price=0; //ストップロスレート,利確レート,エントリーレート
bool OrderKekka;
          
//---
   //新しい足ができた時だけやる
   if(Time[0] != prevtime){
      prevtime = Time[0];
   }else{
      return(0);
   }
           
//***売買判断箇所***//
          
   //チェック用変数の初期化
   TopPoint=0;
   BottomPoint=0;   
       
   //ZigZagの高値安値を構造体に再セット
   getZigZag(1);
       
       
   //高値切り上げ安値切り上げでロング
   if(ZigTop[0] > ZigTop[1] && ZigTop[1] > ZigTop[2] && 
      ZigBottom[0] > ZigBottom[1] && ZigBottom[1] > ZigBottom[2] && BottomPoint==1)
   {
      orderPtn=1;
   }
   //高値切り下げ安値切り下げでショート 
   else if(ZigTop[0] < ZigTop[1] && ZigTop[1] < ZigTop[2] &&
      ZigBottom[0] < ZigBottom[1] && ZigBottom[1] < ZigBottom[2] && TopPoint==1)
   {
      orderPtn=2;
   }
   else
   {
      orderPtn=0;
   }
       
//***売買判断箇所***//
           
       
//***決済判断箇所***//
   total=OrdersTotal();
   maisuu = Lots;
   
   //ナンピン処理
   if(total > 0 && orderPtn > 0){ 
      OrderKekka = OrderSelect(total-1,SELECT_BY_POS,MODE_TRADES);
      if(OrderType()==OP_BUY && orderPtn == 2){
         orderPtn =0;
      }else if(OrderType()==OP_SELL && orderPtn == 1){
         orderPtn =0;
      }
      if(OrderType()==OP_BUY && (OrderOpenPrice() - 40 * Point < Ask)){
         orderPtn =0;
      }else if(OrderType()==OP_SELL && (OrderOpenPrice() + 40 * Point  > Bid)){
         orderPtn =0;
      } 
    
      //既にナンピンを4回している場合は追加ナンピンしない
      if(total>3){
         orderPtn =0;
      }else{
         if(orderPtn !=0){
            maisuu = (Lots + Lots) * OrdersTotal();
            if(maisuu==(Lots + Lots) * 3){
   
               //3つ目のポジションのSLの値と建値の値を取得する
               OrderKekka = OrderSelect(2,SELECT_BY_POS,MODE_TRADES);              
               //2つ目のポジションのSLとTPを変更する(SL:3つ目のポジションのSLに変更、 TP:3つ目のポジションの建値に変更)                          
               OrderKekka = funcOrder_Modify(OrderStopLoss(),OrderOpenPrice(),1);  
   
   
               //再度3つ目のポジションのSLの値と建値の値を取得する
               OrderKekka = OrderSelect(2,SELECT_BY_POS,MODE_TRADES);
               //3つ目のポジションのSLとTPを変更する(SL:3つ目のポジションのSLに変更、 TP:3つ目のポジションの建値に変更)           
               OrderKekka = funcOrder_Modify(OrderStopLoss(),OrderOpenPrice(),2);
   
                  
            }
         }
       }
   }
    
   if(orderPtn > 0)   
   {
      if(orderPtn == 1)
      {
         ea_order_stop_price = Ask - STOP_LOSS * Point;
         ea_order_good_price = Ask + TP * Point;          
      }
      else if(orderPtn == 2)
      {
         ea_order_stop_price = Bid + STOP_LOSS * Point;  
         ea_order_good_price = Bid - TP * Point;  
      }   
          
      //新規注文
      OrderKekka = funcOrder_Send(orderPtn - 1,ea_order_stop_price,ea_order_good_price,0,0);
          
   }
             
   return(0);
}
          
//+------------------------------------------------------------------+
//|【関数】新規注文関数                                                 |
//|                                                                  |
//|【引数】 ea_order_entry_Type:売買(0:買 1:売)                         |
//|【引数】 ea_order_stop_price:損切値  ea_order_good_price:利確値      |
//|【引数】 orderComment:オーダーコメント    ea_order_MagicNo:マジックNo       |
//|                                                                  |
//|【戻値】True:成功                                                   |
//|                                                                  |
//| 
bool funcOrder_Send(int ea_order_entry_Type, double ea_order_stop_price, double ea_order_good_price,int orderComment,int ea_order_MagicNo)
{
           
   int order_resend_num;        // エントリー試行回数
   int ea_ticket_res;           // チケットNo
   int errorcode;               // エラーコード
   double ea_order_entry_price; // エントリーレート
   color order_Color;
   bool kekka;
              
   for( order_resend_num = 0; order_resend_num < 10; order_resend_num++ ) {    // エントリー試行回数上限:10回
           
      if(MarketInfo(NULL,MODE_SPREAD) < A_SPREAD ){
           
         if(ea_order_entry_Type == OP_BUY){   
            ea_order_entry_price = Ask;               // 現在の買値でエントリー
            order_Color = clrBlue;
            Print(Ask+"でロングするよ!");            
         }else if(ea_order_entry_Type == OP_SELL){        
            ea_order_entry_price = Bid;               // 現在の売値でエントリー
            order_Color = clrRed;
            Print(Bid+"でショートするよ!");                       
         }
           
         // FXCMでは新規エントリー時にストップ/リミットを設定出来ない。
         ea_ticket_res = OrderSend(   // 新規エントリー注文
            NULL,                 // 通貨ペア
            ea_order_entry_Type,      // オーダータイプ[OP_BUY / OP_SELL]
            maisuu ,                    // ロット[0.01単位](FXTFは1=10Lot)
            ea_order_entry_price,     // オーダープライスレート
            20,                       // スリップ上限    (int)[分解能 0.1pips]
            ea_order_stop_price,      // ストップレート
            ea_order_good_price,      // リミットレート
            orderComment,             // オーダーコメント
            ea_order_MagicNo,         // マジックナンバー(識別用)
            0,                        // オーダーリミット時間
            order_Color               // オーダーアイコンカラー
            );
  
         Print("結果:"+ea_ticket_res);
  
         if ( ea_ticket_res == -1) {            // オーダーエラー
            errorcode = GetLastError();      // エラーコード取得
              
            if( errorcode != ERR_NO_ERROR) { // エラー発生
               printf("エラー");
            }
              
            Sleep(2000);                                           // 1000msec待ち
            RefreshRates();                                        // レート更新
              
            printf("再エントリー要求回数:%d, 更新エントリーレート:%g",order_resend_num+1 ,ea_order_entry_price);
              
         } else {    // 注文約定
            Print("新規注文約定。 チケットNo=",ea_ticket_res," レート:",ea_order_entry_price);
            Sleep(300);                                           // 300msec待ち(オーダー要求頻度が多過ぎるとエラーになる為)
                          
            break;
         }
  
              
              
      }else{
         Print("スプレッドNG 許容スプレッド:"+A_SPREAD+"pips未満 環境スプレッド:"+MarketInfo(NULL,MODE_SPREAD)+"pips");
         Sleep(2000);                                           // 2000msec待ち
         RefreshRates();     
      }
                       
  
   }
   return kekka;   
}
//+------------------------------------------------------------------+
//|【関数】トレール(変更注文)関数
//|
//|【引数】 order_stop_price:損切値  order_good_price:利確値  cnt:何個目のポジションを変更するかの値
//|
//|【戻値】True:成功 False:失敗
//|
//|    
bool funcOrder_Modify(double order_stop_price, double order_good_price,int cnt)
{
   bool kekka,OrderKekka;
   int total,order_resend_num,errorcode;
   
   kekka=false;
      
   for( order_resend_num = 0; order_resend_num < 20; order_resend_num++ ) {   
      
      total=OrdersTotal();
         
      if(total >0 && OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES)==true){
         OrderKekka = OrderModify(OrderTicket(),OrderOpenPrice(),order_stop_price,order_good_price,0,clrYellow);
   
         if(OrderKekka==false){
            errorcode = GetLastError();
            
            Print("変更注文失敗 エラーNo=",errorcode," リトライ回数=",order_resend_num+1," SL=",order_stop_price,"TP=",order_good_price);
               
               
            //損切り・利確値が不正な場合は微調整する
            if(errorcode==ERR_NO_RESULT || errorcode==ERR_INVALID_STOPS){
               if(OrderType() == OP_BUY){
                  order_stop_price = order_stop_price - 5 * Point;
                  order_good_price = order_good_price + 5 * Point;
               }else if(OrderType() == OP_SELL){
                  order_stop_price = order_stop_price + 5 * Point;
                  order_good_price = order_good_price - 5 * Point;            
               }
            }
               
            RefreshRates();
            Sleep(5000);
         }else{
            Print("変更注文完了。 SL=",order_stop_price," TP=",order_good_price);
            
            kekka=true;
            break;
         }
      }
   }
      
   return kekka;   
}
   
//+------------------------------------------------------------------+
//|【関数】ジグザグの値をセット
//|
//|
//|【備考】なし
//+------------------------------------------------------------------+
bool getZigZag(int i)
{
       
int n,m,t;
       
bool kekka;
       
   m=0;
   t=0;
       
          
   kekka=false;
       
   for(n=i;n<=i+200;n++)
   {
      //ZigZagの値を取得
      double Zg=NormalizeDouble(iCustom(NULL,0,"ZigZag",E_Depth,E_Deviation,E_Backstep,0,n),5);
       
      //ZigZagの値と最高値が同じ場合、頂点なのでZigTopにセット      
      if(Zg!=0 && Zg==NormalizeDouble(High[n],5))
      {
         if(n==1){
            TopPoint=1;
         }
                
         ZigTop[m++]=Zg;
         if(m>=4)break;
      }
             
      //ZigZagの値と最安値が同じ場合、底なのでZigBottomにセット            
      if(Zg!=0 && Zg==NormalizeDouble(Low[n],5))
      {
         if(n==1){
            BottomPoint=1;
         }
                      
         ZigBottom[t++]=Zg;
         if(t>=4)break;
      }
   }
       
   kekka=true;
          
       
   //目視確認用コメント
   Comment(
          "│ ZigTOP0=", ZigTop[0], "│ ZigBTM0=", ZigBottom[0], "|\n",
          "│ ZigTOP1=", ZigTop[1], "│ ZigBTM1=", ZigBottom[1], "|\n",
          "│ ZigTOP2=", ZigTop[2], "│ ZigBTM2=", ZigBottom[2], "|\n",
          "│ ZigTOP3=", ZigTop[3], "│ ZigBTM3=", ZigBottom[3], "|\n",
          "│ TopP=", TopPoint, "│ BottomP=", BottomPoint, "|\n"
   );
             
          
   return(kekka);   
         
}

前述した修正を加えたZigZagEAのサンプルソースコードになります。

修正内容以外でZigZagのサンプルEA(ナンピン版)からは何も変えていません。

スポンサーリンク

主な構文

ロット数の調整については、特に数値を変えるだけなので構文などはありませんが、指値や逆指値を変更する構文については過去のサンプルソースでもなかったと思うので初となります。

OrderModify()

【使用例】
bool kekka = OrderModify(OrderTicket(),OrderOpenPrice(),order_stop_price,order_good_price,0,clrYellow)

言わずと知れた、変更注文関数ですが今回初使用なのでとりあえず復習も兼ねて引数の説明です。

引数は以下の通りです。

  1. 引数1・・・変更する注文のチケット番号です。(直前にOrderSelect()取得するのが基本)
  2. 引数2・・・待機注文の新しい注文価格です。(私は実際に利用した事ないです)
  3. 引数3・・・新しい逆指値(SL)価格です。
  4. 引数4・・・新しい指値(TP)価格です。
  5. 引数5・・・待機注文の新しい有効期限です。(私は実際に利用した事ないです)
  6. 引数6・・・変更注文時にMT4上に表示させる色です。

引数3と4で注文変更の値を指定する感じですね。

ロット数をナンピン毎に変更し、変更注文も行う

ロット数をナンピン毎に変更するので、まずロット数を設定できるようにしました。

次に、修正する部分としてナンピンするところでロット数の変更と変更注文を行うようにしました。

修正前

//既にナンピンを4回している場合は追加ナンピンしない
if(total>3){
   orderPtn =0;
}

修正後

//既にナンピンを4回している場合は追加ナンピンしない
if(total>3){
   orderPtn =0;
}else{
   if(orderPtn !=0){
      maisuu = (Lots + Lots) * OrdersTotal();
      if(maisuu==(Lots + Lots) * 3){
  
         //3つ目のポジションのSLの値と建値の値を取得する
         OrderKekka = OrderSelect(2,SELECT_BY_POS,MODE_TRADES);              
         //2つ目のポジションのSLとTPを変更する(SL:3つ目のポジションのSLに変更、 TP:3つ目のポジションの建値に変更)                          
         OrderKekka = funcOrder_Modify(OrderStopLoss(),OrderOpenPrice(),1);  
  
  
         //再度3つ目のポジションのSLの値と建値の値を取得する
         OrderKekka = OrderSelect(2,SELECT_BY_POS,MODE_TRADES);
         //3つ目のポジションのSLとTPを変更する(SL:3つ目のポジションのSLに変更、 TP:3つ目のポジションの建値に変更)           
         OrderKekka = funcOrder_Modify(OrderStopLoss(),OrderOpenPrice(),2);
  
           
      }
   }
 }

4つめのポジションを持つ際、2つ目と3つ目のSLとTPを変更しています。OrderSelect()関数でSLとTPを変更するポジションを選択し、変更注文用の自作関数funcOrder_Modify()で変更しています。

主な変更点は以上です。

さいごに

以上、『ZigZagEAにロット数調整や指値変更処理を組み込む』EAのサンプルソースでした。

ここまでくれば実用化も見えてきますが、ナンピン・微マーチンゲール系なので安定して勝てるけど、崩れた時が怖いかなと言う印象です。

もしご使用になる場合は自己責任でご使用下さい



※ EAのサンプルソースを一覧表にまとめました

※オンラインレッスンやってます


コメント

  1. musashi より:

    初めまして、musashiといいます。お世話になっております。

    mql勉強中で今回サンプルソースのアリゲーターとジグザグをコンパイルさせて頂き、エラーが出なかったので、バックテストも通過してデモ口座で両方のEAを推奨の時間足と1分足で回しているのですが、

    エントリーしてくれません。

    因みにアリゲーターのターミナルのエキスパートタブには、

    (2021.04.08 12:57:10.223 アリゲーター USDJPY,M1: 新規注文約定。 チケットNo=0 レート:0)

    これが連発します。

    お忙しいところ恐縮ですが、ご教授いただければ幸いです。

    宜しくお願い致します。

    • りょう りょう より:

      はじめまして、管理人のりょうです。

      海外ブローカーのデモ口座使ってる感じでしょうか?
      その場合、スプレッドが1銭以上あいてたら新規注文がブロックされる部分で引っかかってる可能性が高いです。

      アリゲーターとジグザグの各ソースを『if(MarketInfo(NULL,MODE_SPREAD) < 10){』で検索してもらって(1か所だけヒットします) 『if(MarketInfo(NULL,MODE_SPREAD) < 10){』 を 『if(MarketInfo(NULL,MODE_SPREAD) < 30){』 に変更して再度コンパイルして頂くと3銭まで許容する形になります。この内容で一度お試し頂けないでしょうか。

    • りょう りょう より:

      この記事のサンプルソースのみですが、取り合えず許容スプレッド設定を追加してみました。
      3銭まで許容したい場合は、A_SPREAD設定を30として下さい。

      • musashi より:

        こんばんは、musashiです。

        お返事、ありがとう御座います。
        おっしゃるとうりXMのデモ口座で回してダメでしたが、

        if(MarketInfo(NULL,MODE_SPREAD) < A_SPREAD){
        A_SPREAD = 変更してエントリー確認できました。

        アリゲーターも(A_SPREAD) 入れてinput int A_SPREAD = 30;
        エントリー確認できました。

        少し回して結果を見たいと思いますとても楽しみです。

        ありがとうございました。

  2. musashi より:

    こんばんは、musashiです。

    お返事、ありがとう御座います。
    おっしゃるとうりXMのデモ口座で回してダメでしたが、

    if(MarketInfo(NULL,MODE_SPREAD) < A_SPREAD){
    A_SPREAD = 変更してエントリー確認できました。

    アリゲーターも(A_SPREAD) 入れてinput int A_SPREAD = 30;
    エントリー確認できました。

    少し回して結果を見たいと思いますとても楽しみです。

    ありがとうございました。

  3. コム より:

    お世話になっております。
    コムと申します。

    MQL言語を現在勉強中でこちらの記事に辿り着きました。
    突然のご質問、大変恐縮ですがご教示いただきたくコメントいたします。

    御HPでもマジックナンバーの重要については記事がありましたが
    このEAの場合はマジックナンバーはどこに記載されているのでしょうか。
    また、マジックナンバーを記載する場合はどのように記載するべきでしょうか。

    funcOrder_Send
    上記関数をググって見ましたがどこにも記載がなく、ご教示いただけましたら幸いです。

    XMリアルマイクロ口座のストラテジーにてUSDJPY15分足でテストしたところ
    2021.04.18 21:54:05.640 2021.02.04 17:00:00 ZigZag USDJPYmicro,M15: array out of range in ‘ZigZag.mq4’ (161,32)
    と出てしまいますがどのように対処するべきでしょうか。
    ※他通貨ではエラー表示なし(AUD JPY)

    お忙しい中大変恐縮ですがご対応ご教示のほどよろしくお願い致します。

    • りょう りょう より:

      はじめましてコムさん、管理人のりょうです。

      申し訳ございません。こちらのEAのマジックナンバーについては、0固定になっております。なので、このサイトのサンプルソースは1つのFX口座でこのEAだけ使う分には問題ないですが、1つのFX口座で複数EAを動かす分には使えません。

      funcOrder_Send()は私が自作している関数です。サンプルソースの162行目あたりからがその内容になります。
      ※新規注文するOrderSend()関数もそこに記載されています

      『array out of range』は見たことが無かったので少し調べてみたのですが、配列エラー?だそうです。
      USDJPY15分足のテストデータが最近のデータしかなかったりしませんか?
      テスト期間を2021年4月からにしても同じエラーになりますでしょうか?

  4. コム より:

    ご返信いただきありがとうございます。

    関数って自身で作ることもできるのですね。
    勉強になりました。

    ちなみにご開示できる内容か分からず質問してしまい恐縮ですが、
    funcOrder_Sendについて、真偽値を返すような関数となっているように見えますが
    どのような活用方法で作成されているのでしょうか。

    array out of rangeについてお調べいただきありがとうございます。
    本件についてはロット数を1=1000通貨にしたところエラーがでなくなりました。
    0.01=10通貨が良くなかったのかも?しれません。
    お騒がせ致しました。

  5. きち より:

    はじめまして。違う時間足で同じ例えば4時間足が戻り高値を抜いた(条件)で15分足も同じ減少が起きたら買いなどできますでしょうか?ご教授願います。

  6. takahiro より:

    はじめまして、質問させてくださいよろしくお願いします。

    Tester: cannot load Experts\ZZsample
    とでます。

    int start()はインジケーターでないとだめでしょうか?

    何時も参考にさせていただいてますありがとうございます。

    • りょう りょう より:

      はじめまして!

      多分、ZZsampleというEAが無い(みつからない)という問題なのかなと思います。
      もし動くEAがあればそのソースコードを丸々消して、ZigZagのソースコードを丸々コピペしてコンパイルすると動くと思いますがどうでしょうか?
      ※動くEAのソースコードはどこか別の所に退避してください

  7. Masa より:

    はじめまして、Masaと申します。コメント失礼いたします。

    このブログを拝見させていただき、とても勉強になっています。

    そこで質問させていただきたいのですが、先のコメントの中でマジックナンバーは0固定とのことですがマジックナンバーを任意の番号へ変更したい場合、ソースコード冒頭部分に
    input int MagicNumber = 123456; //マジックナンバー
    を記述したとして、どこの部分をMagicNumberへ変更すればよいかご教授頂くことは可能でしょうか。

    お忙しいところ恐れ入りますがよろしくお願い致します。

  8. りょう りょう より:

    はじめましてMasaさん。ブログ見て頂き有難うございます。

    マジックナンバーを任意の番号へ変更したい場合、以下のようにすると新規注文時にマジックナンバーが設定されるようになります。
    OrderKekka = funcOrder_Send(orderPtn – 1,ea_order_stop_price,ea_order_good_price,0,MagicNumber);

    あと、このプログラムは変更注文もあるのでそこでもマジックナンバーを見てあげる必要があります。

    • Masa より:

      ご返答ありがとうございます。

      早速教えていただいたことを基にやってみたいと思います。

      ありがとうございました。

  9. MASA より:

    お世話になっております。MASAです。

    追加で質問させていただきたいのですが、このロジックのソースコードだと可能性としては
    両建てもあり得るのでしょうか?

    お忙しいところ恐れ入りますがよろしくお願い致します。

    • りょう りょう より:

      両建てはあり得ませんよー。
      このロジックは最初にエントリーしたポジションを見て同じ方向に最大4回エントリーする形となっています。
      例えばロングポジション保持中にショートエントリーサインが出たとしてもそのショートエントリーサインは無視されます。

  10. より:

    はじめまして。

    初心者のため初歩的な質問になってしまいますが、
    コメントを入れる場合、どのようにしたらいいのでしょうか?

    宜しくお願い致します。

    • りょう りょう より:

      はじめまして。

      コメントは、行の先頭を//とするとその行はコメントになります。

      例)
      ① a = a + b;
      ②//a = a + b;

      ①の方は計算されますが、②はコメントになっているので計算されずプログラムには一切影響されなくなります。

      • より:

        早速のご回答ありがとうございます。
        この度質問したコメントですが、
        エントリーした際にターミナルの項目の
        コメント欄に記載されるコメントの件です。

        説明が足りなくて申し訳ございません。

        現在のソースですと、OrderKekkaの”0”になっている箇所かと思いますが、
        まだまだ理解が浅くわからず・・・

        お手数をおかけしますがご教授お願い致します。

        • りょう りょう より:

          なるほど、そちらのコメントでしたか!
          それですと、以下の1文があると思いますが

          OrderKekka = funcOrder_Send(orderPtn – 1,ea_order_stop_price,ea_order_good_price,0,0);

          ここの最後から2つ目の所

          OrderKekka = funcOrder_Send(orderPtn – 1,ea_order_stop_price,ea_order_good_price,”test”,0);

          等にして頂くとコメント入れられます。
          が、ちょっと作りに問題あって数値しかコメント入れられなくなっていました。

          文字のコメントも対応する場合、もう1か所の修正するところがあって新規注文関数の所
          bool funcOrder_Send(int ea_order_entry_Type, double ea_order_stop_price, double ea_order_good_price,int orderComment,int ea_order_MagicNo)

          のint orderCommentってなっている所をstring orderCommentに変えて頂くと可能となります。

  11. より:

    デモ口座にて実際の動きを見ている中で、2点質問があります。

    1.ナンピンが発動された際、1ポジション目、2ポジション目、3ポジション目、4ポジション目とそれぞれのTP・SLとなりますが、私の認識でのナンピンは、複数ポジションになった時に合算・平均からのTP・SLが再設定ということかと思っておりますが、それぞれのポジションのTP・SLの固定は仕様なのでしょうか?

    2.パラメータにて設定した初期ロットでエントリーされない事が多々あります。
    例えば、初期ロットを0.03と設定しているのに、1ポジション目で0.06でエントリーされたり、0.12でエントリーされたりなどなど
    これは、バグでしょうか?

    • りょう りょう より:

      1.こちらのナンピンについては仕様です。厳密な平均等は計算しておらず1ポジション目の損失を抑える形で以降ポジションを持つ仕組みにしています。
      2.それは意図した動きではないのでバグです。実際の環境だと起きるのかな、1ポジション目が何かの原因でエントリーされず2ポジション目から入ってるような気がします。また見てみます。

  12. しんぷそん より:

    大変勉強させていただいてます。
    こちらのサンプルコードのまま過去検証を行ったところロングのみエントリーされショートは一度もエントリーされませんでした。
    エキスパート設定上ではロングとショートどちらもエントリーできる設定にしています。
    ショートもエントリーするようにしたいのですがどういったことが原因でロングのみになっているかわかりません。
    ご教授いただけると幸いです。

    • りょう りょう より:

      しんぷそんさん

      有難うございます。
      バックテスト中の操作履歴に『[価格]でショートするよ!』という文言は一切出ていないでしょうか?
      ロングされているという事は、『[価格]でロングするよ!』という文言は多分出ていると思うので一度それをご確認頂いてもよろしいでしょうか。

      • しんぷそん より:

        返信ありがとうございます。
        ロングするよは表示されています。
        ショートするよの表示はありません。
        テスト結果でも売りポジションのエントリー数は0のままになっています。

        • りょう りょう より:

          という事は全く売り条件を満たしていないという事になりますね・・・。
          バックテスト時ですが、『始値のみ』で確認されていますでしょうか?
          あと私も確認したいので、よければ以下を教えて頂けないでしょうか。
          ①通貨ペア
          ②時間足
          ③テスト期間
          ④わかればテストデータの入手元

          • しんぷそん より:

            始値のみになっています。
            ①USD/JPY
            ②15分足
            ③2016/01/01から2021/04/03
            ④TitanのMT4上でダウンロードしました。

  13. テストマン より:

    私もTitanのデモ口座で以下の状態でバックアップテストしてみましたが、
    取引数7911、買い4000回、売り9311、連敗数7911で1回も勝ちトレードなしでした。

    ①USD/JPY
    ②15分足
    ③2000/01/01から2024/01/13
    ④TitanのMT4上でダウンロードしました。
    ⑤始値のみになっています。

  14. ラドロー より:

    また、質問すみません

    ポジションをもったら、そのポジションを決済するまで
    次のポジションを持たないようにするのはどうすれば良いでしょうか?

    詳細
    (0.01でポジションを持ってる最中に0.02のポジションを持つ時があります)
    0.01のポジションが決済してから0.02のポジションを持つようにしたいです。

    お手数お掛けしますがよろしくお願いいたします。

    • りょう りょう より:

      ラドロー さん

      この記事のプログラムは、4ポジションを想定したものになっておりますので1ポジずつにすると思ったようなパフォーマンスは発揮できないかもしれません。

      それでも1ポジションずつのトレードとする場合は131行目を、
      if(total == 0 && orderPtn > 0) と変更し、92行目~129行までのソースコードを削除してみてください。