新型MQL4で台無しになった小額紙幣管理-Indicator

 

こんにちは、コーダーの皆さん。

私は小さなMoneymanagementのインジケータを作りました。しかし、新しいMQL4になってから、私の手には負えない問題が発生しました。

このインジケータをチャートにドラッグすると、右側にいくつかの数字が表示されます。最初の数字はストップロス(ピップ)を意味し、2番目の数字はロットサイズです。オプションでリスクを選択することができます。もう一つの数値はストップロス・レベルです。しかし、通貨ペアを 変更すると、この数字は消えてしまいます。代わりに「Label」という文字が何度も出てきます。そして、インジケーターリストを見ると、私のインジケーターも消えています。つまり、通貨ペアを変えたら、インジケータがなくなり、数字の代わりにLabelが残ったということです。

全くもって困惑しています。以前はこのインジケータは問題なく動いていたのですが。助けていただけると幸いです。

以下がそのコードです。

#property indicator_chart_window
//--- input parameters
extern int  Risk=2;
extern int SL_Levels=20;
int multi, exp, SL, i, k;
double MoneyRisk, Spread, _modifySpread, lots;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   k=0;
   for(i=1; i<=SL_Levels; i++)
   {
      if (ObjectFind("SL"+i) == -1)
      {
         ObjectCreate("SL"+i, OBJ_LABEL, 0, 0, 0);
         ObjectSet("SL"+i, OBJPROP_CORNER, 1);
         ObjectSet("SL"+i, OBJPROP_XDISTANCE, 3);
         ObjectSet("SL"+i, OBJPROP_YDISTANCE, k);
         k=k+15;    
      }
   }
   if (ObjectFind("Spread") == -1)
   {
      ObjectCreate("Spread", OBJ_LABEL, 0, 0, 0);
      ObjectSet("Spread", OBJPROP_CORNER, 3);
      ObjectSet("Spread", OBJPROP_XDISTANCE, 3);
      ObjectSet("Spread", OBJPROP_YDISTANCE, 1);
   }
   
//-- 4 / 5 Digit Settings --
   multi   = 1;
   exp     = 0;
   if (Digits==5 || Digits==3)
   {
      _modifySpread = 0.1;
      multi=10;
      exp=1;
   }
//----
   SL = MathFloor((iATR(NULL, PERIOD_D1, 7, 0)*MathPow(10,Digits-exp)+1)*0.1);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   for(i=1; i<=SL_Levels; i++)
   {
      ObjectDelete("SL"+i);
   }
   ObjectDelete("Spread");
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
//----
   Spread     = MarketInfo(Symbol(), MODE_SPREAD)*_modifySpread;
   MoneyRisk  = AccountBalance()*Risk*0.01;
   k=0;
   for(i=1; i<=SL_Levels; i++)
   {
      lots=MoneyRisk/SL/(MarketInfo(Symbol(), MODE_TICKVALUE)*multi);
      ObjectSetText("SL"+i, SL+ " : "+DoubleToStr(lots, 2), 10, "Calibri", Red);
      k=k+15;
      SL = SL+MathFloor(((iATR(NULL, PERIOD_D1, 7, 0)*MathPow(10,Digits-exp)+1)*0.1)/2);     
   }
   SL = MathFloor((iATR(NULL, PERIOD_D1, 7, 0)*MathPow(10,Digits-exp)+1)*0.1);
   ObjectSetText("Spread", DoubleToStr(Spread,1), 10, "Calibri", Red);
   WindowRedraw();
//----
   return(0);
  }
//+------------------------------------------------------------------+
 

まず、"exp "をintに使うことはできません。

次に、"SL "を表現すると

SL = MathFloor((iATR(NULL, PERIOD_D1, 7, 0)*MathPow(10,Digits-exp)+1)*0.1);

を使うことはできません。

なぜなら、もしエラー4066が 発生したら、"SL"=0になるからです。

となると、"lots "の除算はゼロに なります。

lots=MoneyRisk/SL/(MarketInfo(Symbol(), MODE_TICKVALUE)*multi);

を表現すると、インジケータが停止し、インジケータを再ロードする必要があります。

 
理解できました。ちょうど変数expを変更しましたが、エラー4066を確認 または回避する方法を教えていただけませんか?MetaTraderが現在のチャートと時間枠の相場だけを更新するという事実と関係があると読みました。しかし、4066を避けるためにはどうしたらよいのでしょうか?
 

更新を避けることはできませんが、"ゼロ除算"の事態は避けなければなりません。

そのため、変数のいずれかが0に等しいかどうかをチェックする必要があります...ゼロ除算を回避する場合

そして、インジケータを停止することはできないので、何かを考えなければなりません。

の例です。

SL = MathFloor((iATR(NULL, PERIOD_D1, 7, 0)*MathPow(10,Digits-exp)+1)*0.1);
if (SL == 0) // because error 4066 (for example)
   {
   SL = Someting;
   }
lots=MoneyRisk/SL/(MarketInfo(Symbol(), MODE_TICKVALUE)*multi);
 

そうですね...。避けることはできませんね :-)

私が言いたかったのは、更新が完了するまで待ってからSLの計算を続けることはできるのか、ということです。問題は、SLにランダムな値を与えることができないことで、そうするとインジケータ全体が無駄になってしまいます。そこで、エラー4066が発生しないかどうか確認 し、発生した場合は何とか待って、再度確認した上で次に進みたいと思います。

 

ところで、私もこのインジケータで同じ問題を抱えています。しかし、なぜ「古い」MetaTraderでは問題なかったのでしょうか?ここでは、私はいつもATR(5)のためにゼロを受け取ります。なぜだ!!!?以前はそんなことなかったのに...。この新しいMetaTraderは嫌いです...!

int start()
//----
  {
   double Spread = MarketInfo(Symbol(), MODE_SPREAD);
   double ATR = iATR(NULL, PERIOD_D1, 5, 0);
   int exp1 = 0;
   if (Digits==5 || Digits==3)
   {
      Spread=Spread*0.1;
      exp1 = 1;
   }
   Comment  (
            "ADR(5): ",DoubleToStr(ATR*MathPow(10,Digits-exp1),1),
            " || TODAY: ",(iHigh(NULL, PERIOD_D1, 0)-iLow(NULL, PERIOD_D1, 0))*MathPow(10,Digits-exp1),
            " || ", DoubleToStr(((iHigh(NULL, PERIOD_D1, 0)-iLow(NULL, PERIOD_D1, 0))*MathPow(10,Digits-exp1)/(ATR*MathPow(10,Digits-exp1))*100), 2), "%",
            "\n" +
            "SPREAD: ", Spread,
            " || RATIO: ",DoubleToStr((Spread/ATR)*MathPow(10,-(Digits-exp1-2)), 2),"%"
            );
//----
   return(0);
  }
 
ゼロとはどういう意味ですか?私はすべてのコメントを印刷し、ATR(5)はゼロよりも大きな出力を示しています...実際には50以上...
 

問題が見つかったようです!それは間違いなく更新の問題です。今、通貨を変えると、インジケータは動作します。しかし、その後、私は今日まだ開いていなかった通貨ペアを開きました。すると、こんなメッセージが出ました。


今日まだ開いていないペアを開いてください。D1以外の好きなタイムフレームに切り替えてください。そして、インジケータをチャートにドラッグします。その結果、上記のようなエラーになります。DAILY DATAが欠落しているため、日足チャートのATR(5)が正しく表示されていないようです。D1タイムフレームで「フレッシュ」なチャートを開くと、全く問題がありません。そして、他のタイムフレームに切り替えたときも、ATR(5)が正しいので問題ありません。D1チャートにいる限り、どのペアに切り替えてもいいことに気づきました。しかし、D1 以外のタイムフレームで他のペアに切り替えると、MetaTrader が日足データを受け取っていない限り、問題が発生します。 そこで質問ですが、D1 以外のタイムフレームで新しいチャートを開くときに、ATR 計算が正しいという日足データをどのようにして取得できますか?
 

のようなものを入れておく必要があります。

if(number==0)dothis; else dothis; 

をShowSpread.mq4で表示します。


このゼロ除算が 発生する行を検索すればいいのです。

 
mar:

問題が見つかったようです!それは間違いなく更新の問題です。今、通貨を変えると、インジケータは動作します。しかし、その後、私は今日まだ開いていなかった通貨ペアを開きました。すると、こんなメッセージが出ました。


今日まだ開いていないペアを開いてください。D1以外の好きなタイムフレームに切り替えてください。そして、インジケータをチャートにドラッグします。その結果、上記のようなエラーになります。DAILY DATAが欠落しているため、日足チャートのATR(5)が正しく表示されていないようです。D1タイムフレームで「フレッシュ」なチャートを開くと、全く問題がありません。そして、他のタイムフレームに切り替えたときも、ATR(5)が正しいので問題ありません。D1チャートにいる限り、どのペアに切り替えてもいいことに気づきました。しかし、D1以外のタイムフレームで他のペアに切り替えると、MetaTraderが日足データを受信していない限り、問題が発生します。そこで質問なのですが、D1以外のタイムフレームで新しいチャートを開いたときに、ATR計算が正しいという日足データを得るにはどうしたらいいのでしょうか?
qjolはすでに問題がどこにあるか言った。もしあなたが助けを求めているのなら、人々があなたにアドバイスしたことに従うか、少なくとも確認 しませんか?
 

angevoyageurさん、私からのこの投稿はご覧になっていないようですね。

mar 2014.04.02 08:16#

おっしゃる通りです...。避けることはできませんね :-)

"私が言いたかったのは、アップデートが完了するまで待ってからSL-calculationに進むことは可能でしょうか?問題は、SLにランダムな値を与えることができないことです、そうするとインジケータ全体が無駄になってしまいます。そこで、エラー4066をチェックし、発生したら、何とか待って、再度チェックしてから、先に進みたいのです。"

そこには、アドバイスに従えないことが記述されており、その解決策に至ったので、qjolさんがアドバイスしてくれたことを間違いなく確認したこともわかりますね。

理由: