(インジケーター)ニャン吉グリッド

ニャン吉が普段FXで使っているMT4用の価格表示グリッドです。
たぶんネット上に転がっている価格グリッドよりは見やすいのではないかと思います。
また、ネットに転がっているものよりは安全だと思い公開することにしました。

但しブログに貼った時点では安全なソースコードであることを確認してありますが、公開日以降の確認はしておりませんので改変・ハッキング被害等の保証はできません。
ご利用は自己責任のうえLive口座での本稼働は避けるようにお願いします

これはインジケーターであってEAではないのですが、コード登録の仕方・チャートへの貼り方は全く同じで構いません。

MT4の画面ですと「自動売買」ボタンの左3つ隣に「メタクウォーツ言語エディタ」ボタンがあり、それを押してMetaEditorを開いてから「新規作成」ボタンを押してコードをコピペしてから任意の名前を付けて保存して「コンパイル」ボタンを押せば、MT4再起動後「ナビゲーター」の「インディケータ」から個別のチャートへ貼る事でインジケーターの稼働ができるはずです。

//+------------------------------------------------------------------+
//|                                                      ニャン吉グリッド |
//|                                     Copyright 2021, ニャン吉ちゃんねる |
//|                                          https://ニャン吉ちゃんねる.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, ニャン吉ちゃんねる"
#property link      "https://ニャン吉ちゃんねる.com"

#property indicator_chart_window
extern int GridSpace=1000;

int deinit()
  {
   double shift=0;
   double HighPrice=0;
   double LowPrice=0;

   double Divisor=0.1/Point;

   HighPrice=MathRound(High[Highest(NULL,0,2, Bars - 2,  2)] * Divisor);
   LowPrice=MathRound(Low[Lowest(NULL,0,1, Bars - 1, 2)] * Divisor);
   for(shift=LowPrice;shift<=HighPrice;shift++)
     {
      ObjectDelete("Grid"+shift);
     }
   return(0);
  }

int start()
  {
   int    counted_bars=IndicatorCounted();
   double I=0;
   double HighPrice=0;
   double LowPrice=0;
   int GridS=0;
   int SL=0; 
   double Divisor=0.1/Point;

   HighPrice=MathRound(High[Highest(NULL,0,MODE_HIGH, Bars - 2, 2)] * Divisor);
   LowPrice=MathRound(Low[Lowest(NULL,0,MODE_LOW, Bars - 1, 2)] * Divisor);
   GridS=GridSpace/10;

   for(I=LowPrice;I<=HighPrice;I++)
     {
      if (MathMod(I, GridS)==0)
        {
         if (ObjectFind("Grid"+I)!=0)
           {
            ObjectCreate("Grid"+I, OBJ_HLINE, 0, Time[1], I/Divisor);
            ObjectSet("Grid"+I, OBJPROP_STYLE, STYLE_DOT);
            ObjectSet("Grid"+I, OBJPROP_COLOR, Silver);
           }
        }
     }
   return(0);
  }

(EAコード無料公開)ニャン吉Repeat

このEAは指値でのエントリーとトレール決済を繰り返すだけのEAです。
しかも1通貨ペアでは1エントリーしかしないので、複数の通貨ペアで稼働させることを推奨します。
あるいは別チャートに別Magicを割り振って、同一通貨ペアで2ポジション以上を持つことも可能です。
但しこのEAもあくまでニャン吉が自分用として使う前提で制作しています。
ご利用は自己責任のうえLive口座での本稼働は避けるようにお願いします

正直、前回作ったニャン吉EAからRSIとSMAのエントリー条件を削っただけのEAです。
FXの自動売買というよりは裁量取引のサポートツールみたいなEAです。
指定された指値でエントリーをしてトレール決済をするだけのEAですが、同じことを繰り返すだけなので数を並べる事で長期的には威力を発揮します。

前回のEAでは自動売買のイメージから、より有利な価格を探るためにインジケーターと組み合わせることにしましたが、よく考えたら指値を繰り返すだけのほうがエントリーが確実で複数並べてみた場合にはより判り易いのではないかと思って急遽こちらのEAも作ってみました。
設定と工夫次第ではiサイクル(外為オンライン)ループイフダン(アイネット証券)ループイフダン(ひまわり証券)のような使い方もできますが、単純なEAを複数並べて自分で個別に設定をする必要があるので、最初の設定が少し大変かもしれません。数多くの指値を張るためには結構マシンパワーも必要です・・・
また、損切り設定がありませんので、最初に長期的に見てご自身の責任で損失を納得できるロスカットラインを設定して、そこから逆算してロットとポジションと指値を決めていく必要があります。以前「FX勝率100%の方法」で計算方法を紹介しましたが、証拠金・損益シミュレーション | OANDA FX計算ツール (hirose-fx.co.jp)を利用してみてもいいかもしれません。
ニャン吉としては過去20~30年の値幅の外であることがロスカットラインの最低限の条件と考えていますが、これだけは自己責任なのでご自身で納得できる場所であればどこであっても構いません。

指値とトレール決済を繰り返すだけのEAなので、指値を自分で判断して置いていく必要があります。
殆ど同じことが手動でも可能ですが、決済後に何度でも指値を自動で設定してくれることと、このEAでのトレール決済は電源が落ちてもMT4を再起動すればトレールが維持されるため、MT4から一旦ログオフするとトレールストップが決済逆指値に固定されてしまうMT4のものよりも都合が良く気に入っています。
このEAならトレールストップ幅にも制限がないので、その点でもMT4備え付けのトレール機能よりいいです。MT4デフォルトのトレールストップ幅には最低40か50pipsからという制限があって、それ以下だとトレール機能が動作しません(細かい数字は忘れてしまいました><;すみません)。

指値価格については自分で判断するしかないので、少し自動売買のイメージからは離れてしまいますが、エントリー価格が明確に予想できるため完全自動に任せて旅行中や入院中に「エントリーしたかな~できなかったかな~」と思い悩む必要がありません^^;

ニャン吉はFXでは取引手法よりも資金管理を重視していて資金管理に反していなければ何でもいいというスタンスです。
ただ今回は裁量と比べても期待できる収益率が低そうなので、流石に気にはなっていました。
ニャン吉EAでもとりあえずRSIとSMAでエントリーすることにしたのですが、浅い場所で指値が刺さる場合と深い場所で指値が刺さる場合があり、トレール決済とは相性が悪いこともないですがいいとも言えなかったので悩んでいました。

また、このEAのパラメーター設定で決めた指値以外でも指値を置けばそれも有効で、更に裁量指値をEA指値よりも深い場所に置けばEA指値のトレール決済で一緒に処理するので決済指値を決める必要もなく、裁量取引のサポートツールとして使い勝手も良さそうです。
(但し、EAパラメーターでの指値は1通貨ペアにつき1ポジションだけ有効なので、裁量指値のエントリーがEAより先ですとパラメーター上の指値は無視されます。)
複数ポジションを持った場合、EAの指値に対してトレールストップ価格が決まると他全てのポジションにもその逆指値が適用されてしまいます。そのため一番浅く掛かったポジションだけにトレール処理をさせて同通貨ペア他EAのトレール処理命令文を削除しておかないと利益が低くなるだけではなくマイナスでも決算されてしまうポジションが出てきてしまいます。)

とりあえずニャン吉EAと今回のニャン吉Repeatは併用するつもりでいます。
どの通貨ペアにどれというのはまだ悩み中です。
(ニャン吉Repeatでは細かく網を仕掛ける予定ですのでMT4のEA処理がバッティングする可能性が高いです。一旦別口座で20~25ポジション程度の実弾フォワードテストをしてみようと思います。)
(EAコード無料公開)ニャン吉Repeatの補助EA にて不具合への対応が可能です。)

//+------------------------------------------------------------------+
//|                                                      ニャン吉Repeat |
//|                      商用利用及び再配布を禁じます,c2021.5.27,ニャン吉ちゃんねる|
//|                                          https://ニャン吉ちゃんねる.com |
//|                                        (楽天MT4を前提とした設定内容です) |
//+------------------------------------------------------------------+
#property copyright   "商用利用及び再配布を禁じます,c2021.5.27,ニャン吉ちゃんねる"
#property link        "https://ニャン吉ちゃんねる.com"
#property description "(楽天MT4を前提とした設定内容です)"
#property strict

input int    Magic =11;//チャート毎に別ナンバー割り振る(0は避ける)
input double Lot =0.01;//ロット(ロット数よりも通貨ペアを追加してポジション数増を推奨)
input double Kagen =120;//売り指値(指値を置きたくない場合には過去値幅外の数値を入力)
input double Jougen =110;//買い指値
input int TrailingStart =1000;//トレール開始幅(10points=1pip)
input int TrailingStop  =300;//トレールストップ幅
input int MaxSpread  =30;//スプレッドによるエントリー制限
input int MaxSlippage =10;//スリッページによるエントリー制限
double   TakeProfit =0;

   //エントリーカウント
   int CurrentOrder()
    {
   int cnt=0; 
   for(int i=0;i<OrdersTotal();i++) {   
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
      if(OrderSymbol()!=Symbol() || OrderMagicNumber()!=Magic) continue;     
      if(OrderType()==OP_BUY) {
         cnt++;
      }
      if(OrderType()==OP_SELL){
         cnt++;
      }   
    }
    return(cnt);
    }   

void OnTick(void)
  {
   int    cnt,ticket,total;

   if(Bars<100)
     {
      Print("bars less than 100");
      return;
     }

   total=OrdersTotal();   

   if(CurrentOrder()<1)
     {   
     
      if(AccountFreeMargin()<(1000*Lot))
        {
         Print("We have no money. Free Margin = ",AccountFreeMargin());
         return;
        }


    // 買エントリー処理
    if(Ask<Jougen && MarketInfo(Symbol(),MODE_SPREAD)<MaxSpread )
        {
         ticket=OrderSend(Symbol(),OP_BUY,Lot,Ask,MaxSlippage,0,0,NULL,Magic,0,Green);
         if(ticket>0)
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
               Print("BUY order opened : ",OrderOpenPrice());
           }
         else
            Print("Error opening BUY order : ",GetLastError());
         return;
        }

    // 売エントリー処理
    if(Bid>Kagen && MarketInfo(Symbol(),MODE_SPREAD)<MaxSpread )
        {
         ticket=OrderSend(Symbol(),OP_SELL,Lot,Bid,MaxSlippage,0,0,NULL,Magic,0,Red);
         if(ticket>0)
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
               Print("SELL order opened : ",OrderOpenPrice());
           }
         else
            Print("Error opening SELL order : ",GetLastError());
        }
        
      return;
     }

   // トレールストップ処理(同一通貨ペアを複数チャートで稼働させる場合には以下を削除する)
   for(cnt=0;cnt<total;cnt++)
     {
      if(!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
         continue;
      if(OrderType()<=OP_SELL &&    
         OrderSymbol()==Symbol())  
        {

         if(OrderType()==OP_BUY)
           {
            if(TrailingStop>0)
              {
               if(Bid-OrderOpenPrice()>Point*TrailingStart)
                 {
                  if(OrderStopLoss()<Bid-Point*TrailingStop)
                    {
                     if(!OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green))
                        Print("OrderModify error ",GetLastError());
                     return;
                    }
                 }
              }
           }
         else 
           {
            if(TrailingStop>0)
              {
               if((OrderOpenPrice()-Ask)>(Point*TrailingStart))
                 {
                  if((OrderStopLoss()>(Ask+Point*TrailingStop)) || (OrderStopLoss()==0))
                    {
                     if(!OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,OrderTakeProfit(),0,Red))
                        Print("OrderModify error ",GetLastError());
                     return;
                    }
                 }
              }
           }
        }
     }
  }

ニャン吉EAの変更点とバックテスト・プレフォワードテスト

5月5日公開の自分用EAに修正を加えました。主な変更点は以下の通りです。
①エントリーを通貨別に可能にしました(間抜けなのでプレフォワードテストをするまで気が付きませんでした)。
②エントリー条件の「RSI数値が逆転した時」を削除しました。
③エントリー条件に「スプレッド制限」を加えました。
④エントリー条件の「スリッページ制限」を変更可能にしました。
⑤「トレール開始」の条件をトレールストップ幅とは別に変更可能にしました。

5月5日公開の自分用EAの記事下部に貼ってあるコードに以上の変更点を反映させてあります。一旦これでニャン吉EAを完成とします。
もしもエラーや不具合があれば報告を頂けると有難いです。
あくまでニャン吉が自分用として使う前提で制作しています。
ご利用は自己責任のうえLive口座での本稼働は避けるようにお願いします

変更点⑤のトレール処理には悩みました。
本当はマイナススワップ分を取り込み計算して、マイナス分を最低利確幅にするつもりでしたが、ニャン吉の技術力では何の成果も得られませんでした!
代わりにトレール開始幅をトレールストップ幅とは別に設定できるようにしておきましたので、利確幅を操作することで利用者自身が設定をして対応するしかなさそうです。
そのため全自動で勝率100%の目標からはまたしても離れてしまいそうで残念です。
それでも自作トレール処理のほうがMT4デフォルトのトレールストップよりも気に入っています。いつかYouTubeで取り上げたい話題です。

変更点②はバックテストやフォワードテストの挙動をチャートで確認してみると、思った通りには機能していませんでした。
RSIの数値は大きな流れとしての逆転が起こる前にも常に細かく上下し続けているため、意味のない設定となってしまったので削除しました。

変更点①はバックテストのときは1通貨ペアずつ確認していたので気が付きませんでした。
フォワードテストで10通貨ペア以上で確かめたところ、アホなミスに気が付き急いでエントリーカウント条件を追加しました。

今回のニャン吉EAはFXに飽きつつあるニャン吉が、自身の長期FXアカウントで走らせる予定で作りました。
2020年1月以降勝率100%全取引全勝を見える形で維持してきたので、折角だからEAでも勝率100%を狙うつもりで開発を進めてみました。
買い上限・売り下限の設定を加えることによって資金管理との両立がし易く、安易なロジックの割に自分用としては自信を持って稼働できそうです。
しかしながらマイナススワップのポジション保有期間によっては損失が出てしまうので、それにも自動で対応させておきたかったです・・・
マイナススワップへの対応はトレール開始とトレールストップのパラメーター設定で対応をせざるを得ず、この点で悔いがのこります。

まだ他にもこのEAには最大の欠点があります。
高い勝率を維持しつつも、収益率は低くなってしまっている点です。
主要通貨ペアのみ上限下限を余り絞らず日足バックテストをしてみましたが5~10%程度の成績なので、安全のために上限下限を絞るとかなり低い収益率になりそうです。
ここでバックテストの結果を貼らないのは、1年あたりのエントリー数があまりにも少なくバックテストとしてのモデリング品質が低いこと、マイナー通貨ペアでは毎年1エントリーすら期待できない場合があること等、バックテストの結果が期待値にはならないとはっきりと言えるからです。
また、プレフォワードテストはエラーと挙動確認のためだけに行っており、1分足で稼働させていたので成績の参考にもなりません。

他の問題点としてはRSIとSMAを組み合わせたロジックでは利益幅が狭いときもあり、トレールのパラメーター設定で欲張ってしまうと逆方向へ捕まったままになることもあることです。
とはいえ、デフォルトのトレール設定は日足用としては狭いので利益も薄目になっている点を否めません。
この点の改善策として、もっとEAをシンプルにしてエントリー条件を「売り指値・買い指値」のみの設定にする、自動売買というよりも裁量トレードのサポートEAみたいな「ニャン吉Repeat」を次の記事で紹介します。
こちらならトレール設定も幅を取れるので利益幅も期待できますが、ひたすら指値とトレール決済を繰り返すだけのEAとなってしまうので、こまめな指値調整が必要になってしまうかもしれません・・・

ただ、本人としては当初の目的から作った自動売買の「ニャン吉EA」と、サポートEA的な「ニャン吉Repeat」のどちらを自分のLive口座で稼働させるか結構本気で悩んでいます(ノ_く。)