エキスパートアドバイザー - 雑多な質問 - ページ 3

 
double LotCalculator(double lots)
  {
   double minlot  = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN),
          maxlot  = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX),
          lotstep = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
   lots = MathFloor(lots/lotstep)*lotstep;
   lots = MathMax(lots,minlot);
   lots = MathMin(lots,maxlot);
   return(NormalizeDouble(lots,2));
  }
 
honest_knave:
double LotCalculator(double lots){}

とても感謝しています。

私はちょうどそのコードを書き始めたいのです :)

あなたは私を何度も救ってくれました。

本当にありがとうございます。

 
Lot Sizeについても同じメッセージが表示されました。
OnChartEvent()の中で'LotCalculator()'を呼び出しているので、それがいけないのでしょうか
 

私は'MarketInfo & LotSize'計算のための良いフォーラムを探しています。
誰が良いフォーラムのそのタイプを知っている私と共有してください

ありがとうございます。

 
もしかして、私が最後の行(NormalizeDouble)を編集する前に、私のコードスニペットを使ったのでしょうか?私の投稿からあなたの投稿まで3分しかなかったようですが、私はほとんどすぐに編集しています。
 
Max Enrik: 私は自分のEAにNormalizeDoubleを 使用しています。しかし、'NormalizeDouble' のメッセージが気になるのですが、チャート上のロットサイズは このようになっています。0.07

そこで、良いアドバイスが欲しいのですが、お願いします。

02:00:00.069 - custom expert EURUSD,H1: | _lotSize - NormalizeDouble: 0.07000000000000001
02:00:00.069 - custom expert EURUSD,H1: | _lotSize - DoubleToString : 0.07
  1. NormalizeDoubleはdoubleを返します。浮動小数点は小数点以下が無限にあります。それはあなたが浮動小数点を理解していないことと、正確に表現できない数字があることを理解していないことです。(1/10とか。)倍精度浮動小数点フォーマット - Wikipedia, the free encyclopedia == オペランドも 参照してください。- MQL4フォーラム
  2. NormalizeDoubleを 使用しないでください。どのような理由でも。これは、ごまかしであり、使用しないでください。その使用は常に間違って います。
 
whroeder1:
  1. NormalizeDoubleは絶対に 使用しないでください。どんな理由であれ。 これは、クッジであり、使用 しないでください。その使用は常に間違って います。

NormalizeDouble()はまだ必要だと思います。

以下は、あなたのコードスニペットを使った例です(MathFloorを使った私の例も同じです)。

double NormalizeLots(double lots, string pair=""){
    if (pair == "") pair = Symbol();
    double  lotStep     = MarketInfo(pair, MODE_LOTSTEP),
            minLot      = MarketInfo(pair, MODE_MINLOT);
    lots                = MathRound(lots/lotStep) * lotStep;
    if (lots < minLot) lots = 0;    // or minLot
    return(lots);
}

呼び出された。

Print(NormalizeLots(2/3.0));

結果

0.7000000000000001

今、コードを調整しました。

double NormalizeLots(double lots, string pair=""){
    if (pair == "") pair = Symbol();
    double  lotStep     = MarketInfo(pair, MODE_LOTSTEP),
            minLot      = MarketInfo(pair, MODE_MINLOT);
    lots            = MathRound(lots/lotStep) * lotStep;
    if (lots < minLot) lots = 0;    // or minLot
    return(NormalizeDouble(lots,2));
}

結果

0.7


 

 Result: 0.7000000000000001

浮動小数点を理解しておらず、正確に表現できない数字があることを理解していない。(倍精度浮動小数点フォーマット - Wikipedia, the free encyclopedia"のどの部分が不明瞭だったのでしょうか?

NormalizeDouble(0.7, 2)でも全く 同じ結果になります(0.6999999999の可能性もあります。)

 
whroeder1:

浮動小数点を理解しておらず、正確に表現できない数字があることを理解していない。(倍精度浮動小数点フォーマット - Wikipedia, the free encyclopedia」のどの部分が不明だったのでしょうか?

NormalizeDouble(0.7, 2)は全く 同じ結果を生成します(0.69999999999の可能性もあります)。

私はNormalizeDouble()が有効なOrderSendに必要だと言っているのではありません。そのため、私の最初のコードではそれを除外しています。また、浮動小数点数の表現方法についても、私は不明確だとは言っていません。

OPの問題(本質的には表示の問題で、「ロット・ノーマライザ」のコードでNormalizeDouble()を使用するか、値を表示する必要があるときにprintfまたはDoubleToStrを使用することによって解決できます)に対する私の理解により適していると感じたので、それを含めるようにスニペットを編集したのです。

もしかしたら、私はOPを誤解していたかもしれません。

02:00:00.069 - custom expert EURUSD,H1: | _lotSize - NormalizeDouble: 0.07000000000000001
02:00:00.069 - custom expert EURUSD,H1: | _lotSize - DoubleToString : 0.07

(不要な堅苦しさを取り除くために編集しました)

 
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- get minimum stop level
   double minstoplevel=MarketInfo(Symbol(),MODE_STOPLEVEL);
   Print("Minimum Stop Level=",minstoplevel," points");
   double price=Ask;
//--- calculated SL and TP prices must be normalized
   double stoploss=NormalizeDouble(Bid-minstoplevel*Point,Digits);
   double takeprofit=NormalizeDouble(Bid+minstoplevel*Point,Digits);
//--- place market order to buy 1 lot
   int ticket=OrderSend(Symbol(),OP_BUY,1,price,3,stoploss,takeprofit,"My order",16384,0,clrGreen);
   if(ticket<0)
     {
      Print("OrderSend failed with error #",GetLastError());
     }
   else
      Print("OrderSend placed successfully");
//---
  }

MQL4のドキュメントでは、ほとんどの例でNormalizeDouble()関数が使用されているので、これは混乱を招くかもしれません。

また、正規化されていない価格を適用することはできないと警告しているほどです。

成行注文(OP_SELLまたはOP_BUY)の開始時には、Bid(売り)またはAsk(買い)の最新の価格のみが開始価格として使用されます。現在の銘柄と異なる銘柄で操作を行う場合は、MODE_BID または MODE_ASK を指定してMarketInfo() 関数を使用し、その銘柄の最新の気配値を取得する必要があります。

計算値や非正規化値を適用することはできない。要求した建値が価格スレッドに存在しない場合、または小数点以下の桁数に応じて正規化されていない場合、エラー 129 (ERR_INVALID_PRICE) が発生します。要求した建値が完全に古い場合、スリッページパラメータとは別にエラー138(ERR_REQUOTE)を発生させます。要求された価格が期限切れであってもスレッドに存在する場合、注文は現在の価格で、現在の価格が価格+スリッページの範囲内にある場合にのみ開かれます。

そして、MQLに関する優れた書籍のいくつかでも、この方法がかなり多用されています。

用途にもよりますが、表示上の問題は、注文や変更の失敗ほど劇的ではありません。

個人的には、私は常に整数値にアップコンバートしているので、この問題に対処することはほとんどありません。

理由: