エラー、バグ、質問 - ページ 442

 
voix_kas:

どなたか、ボリュームの 有効桁数を計算するコードを準備している方はいらっしゃいませんか?
SymbolInfoInteger(_Symbol, SYMBOL_DIGITS)のようなもので、ボリュームにのみ対応。
例えば、SymbolInfoDouble( _Symbol,SYMBOL_VOLUME_STEP) = "1.0" の場合、答えは "0", "0.1" - "1", "0.01" となる。- "2 "など。

ニュアンスをはっきりさせましょう。0.1"、"0.01"、"0.001 "のようなボリュームステップの場合、私は持っています。

0.2"、"0.11"、"0.023 "など、次のような場合に動作するはずです。

音量に 特化したコードはありません。何にでもあります。

int CountSignedDigits(double x)
{  
  for(int i=0; i<1000; i++,x*=10) if(x-MathFloor(x)<DBL_MIN*2) return i;
  return -1;
}
予告編で確認するための台本です。
ファイル:
_UniTest.mq5  2 kb
 
MetaDriver:
予告編で確認するための台本。
つまり...、注文する前に許容ロットを確認した方がいいと思ったんです。
 
sergeev:
そういうことか...、と思いつつ、発注前に許容ロットを確認した方がいいのかなと思いました。

;)

彼が何を望んでいるのか、よくわからないんです。テレパシーを練習してるんだ;)

 
voix_kas:

どなたか、ボリュームの有効桁数を計算するための既成のコードをお持ちの方はいらっしゃいませんか?
SymbolInfoInteger(_Symbol, SYMBOL_DIGITS)のようなもので、ボリュームにのみ対応。
例えば、SymbolInfoDouble( _Symbol,SYMBOL_VOLUME_STEP) = "1.0" の場合、答えは "0", "0.1" - "1", "0.01" となる。- "2 "など。

ニュアンスをはっきりさせましょう。0.1"、"0.01"、"0.001 "のようなボリュームステップの場合、私は持っています。
0.2"、"0.11"、"0.023 "などの場合、コードが動作するはずです。

具体的にボリュームを出すのは、簡単なことです。

      int N=0;
      double step=SymbolInfoDouble(symbol,SYMBOL_VOLUME_STEP);
      if(step-1.0<0)  N++;
      if(step-0.1<0)  N++;
      if(step-0.01<0) N++;
 

sergeev
MetaDriver
Valmars

よく練られた質問は、答えの半分です。:)すみません、もう寝てしまったので、課題を正確に説明することができませんでした。もう一度挑戦してみます。

取引注文に 正規化されたボリュームを 渡すという話です。
その対価をどうするかである。

MqlTradeRequest TradeRequest;
...
TradeRequest.volume = NormalizeDouble(Volume, GetVolumeDigits(_Symbol));
TradeRequest.price  = NormalizeDouble(Price, SymbolInfoInteger(_Symbol, SYMBOL_DIGITS));
...

価格の正常化......それは誰の目にも明らかだと思います。

私の時(MT4以降)は、MTの記事のどこかに、出来高も正規化するのが望ましいと書いてありました。
実は、ブローカーの条件に従って、出来高の最小値を求めるために、GetVolumeDigits(string Symbol)という関数を書きました。少なくとも2つの実装がある(結果は同じ)。
実装その1

int GetVolumeDigits(string Symbol) {
  int VolumeDigits = 0;
  double VolumeStep = SymbolInfoDouble(Symbol, SYMBOL_VOLUME_STEP);
  while (VolumeStep < 1) {
    VolumeStep *= 10;
    VolumeDigits++;
  }
  return VolumeDigits;
}
実装№2 です。

int GetVolumeDigits(string Symbol) {
  return (int)MathLog10(1.0 / SymbolInfoDouble(Symbol, SYMBOL_VOLUME_STEP));
}

どちらもmin step = 1.0, 0.1, 0.01, 0.001, などのバリエーションで完全に動作します。すなわち,最小ステップが1.0であれば0を,0.1であれば1を返す,という具合である。
例えば、最小ステップが1.1、0.11、0.011の場合はどうでしょうか。このアルゴリズムでは、最下位桁が誤って表示されます。
もちろん、「実際にはそのようなケースはない」と断言してもいい。Expert Advisorでそのような仮想的な可能性を考えるだけにしておきたい。もしかしたら、この件に関して、誰かが経験を共有してくれるかもしれないと思ったので...。

 
voix_kas:
なるほど、VolumeStepの倍数で結果を出したいんですね。まあ、Digitsとは関係なく、まずDigitsで体積を計算 し、それをVolumeStepの倍数に近づけていくのです。
 
voix_kas:

正規化された出来高を 取引注文に 送ることです。
Expert Advisorでこのような仮説の可能性を考えてみたいのです。

どの「仮説」ツールのことを言ってるんだろう?

1.MetaDriverからの バリアントが適しています。CountSignedDigitsは、任意のロットの文字数を表示します。

2.掘る 桁数がわかっていれば、次のように正規化することができます。

double MinLot; // минимальный лот по символу
double MaxLot; // максимальный лот по символу
double LotStep; // шаг лота по символу
int dig; // знаковость лота узнали из функции CountSignedDigits

double NL(double lot)
{
  if (lot<=MinLot) return(MinLot); // проверка на минимальный
  double d=MathFloor((lot-MinLot)/StepLot); // сколько ЦЕЛЫХ шагов умещается в проверяемом лоте
  lot=MinLot+StepLot*d; // рассчитали по этому целому числу
  lot=MathMin(lot, MaxLot);  lot=NormalizeDouble(lot, dig);// не забыли проверить на максимальный // нормализовали
  return(lot); // вернули
}
 

セルゲイエフ
ロット検証機能ありがとうございました。同じような構造・分岐のチェックを使っています。
私の質問は、ロットの中で最も若い場所を見つけること、それを正常化することに重点を置いています。
特に、MetaDriverは「すべて」に対する構築をあげています。:)しかし、欠点がないわけではありません(あるいは私のコンパイラが不具合を起こしている)。以下は、そのコードと実行結果です。

void OnStart() {
  Print(CountSignedDigits(110.0));
  Print(CountSignedDigits(11.0));
  Print(CountSignedDigits(1.1));
  Print(CountSignedDigits(0.11));
  Print(CountSignedDigits(0.011));
  Print(CountSignedDigits(0.0011));
  Print(CountSignedDigits(0.00011));
}

int CountSignedDigits(double x) {  
  for (int i = 0; i < 1000; i++, x *= 10)
    if (x - MathFloor(x) < DBL_MIN * 2)
      return i;
  return -1;
}

結果

2011.07.03 13:15:21     test (EURUSD,M5)        5
2011.07.03 13:15:21     test (EURUSD,M5)        4
2011.07.03 13:15:21     test (EURUSD,M5)        18      -    Здесь только у меня бяка вылазиет?
2011.07.03 13:15:21     test (EURUSD,M5)        2
2011.07.03 13:15:21     test (EURUSD,M5)        1
2011.07.03 13:15:21     test (EURUSD,M5)        0
2011.07.03 13:15:21     test (EURUSD,M5)        0

次のオプション(CountSignedDigits関数も同じ)。

void OnStart() {
  double value = 110.0;
  int count = 9;
  while (count) {
    Print(DoubleToString(value), " - ", CountSignedDigits(value));
    value /= 10;
    count--;
  }
}

結果

2011.07.03 13:23:32     test (EURUSD,M5)        0.00000110 - 22       -   Почему-то здесь бяка...
2011.07.03 13:23:32     test (EURUSD,M5)        0.00001100 - 21       -
2011.07.03 13:23:32     test (EURUSD,M5)        0.00011000 - 5
2011.07.03 13:23:32     test (EURUSD,M5)        0.00110000 - 4
2011.07.03 13:23:32     test (EURUSD,M5)        0.01100000 - 3        - Здесь уже все нормально. Почему результаты разные?!
2011.07.03 13:23:32     test (EURUSD,M5)        0.11000000 - 2
2011.07.03 13:23:32     test (EURUSD,M5)        1.10000000 - 1
2011.07.03 13:23:32     test (EURUSD,M5)        11.00000000 - 0
2011.07.03 13:23:32     test (EURUSD,M5)        110.00000000 - 0
 

OnStartの以下の行を変更しました。

double value = 210.0;

結果

2011.07.03 13:28:01     test (EURUSD,M5)        0.00000021 - 23
2011.07.03 13:28:01     test (EURUSD,M5)        0.00000210 - 22
2011.07.03 13:28:01     test (EURUSD,M5)        0.00002100 - 21
2011.07.03 13:28:01     test (EURUSD,M5)        0.00021000 - 20
2011.07.03 13:28:01     test (EURUSD,M5)        0.00210000 - 19
2011.07.03 13:28:01     test (EURUSD,M5)        0.02100000 - 3
2011.07.03 13:28:01     test (EURUSD,M5)        0.21000000 - 2
2011.07.03 13:28:01     test (EURUSD,M5)        2.10000000 - 1
2011.07.03 13:28:01     test (EURUSD,M5)        21.00000000 - 0
2011.07.03 13:28:01     test (EURUSD,M5)        210.00000000 - 0

私のやり方が間違っているのか(修正してください)、MetaDriverが(アルゴリズムを設計 する際に)理論的に間違えたのか、どちらかです。

 
voix_kas:

私の質問は、正規化するためにロットの中で最も低い場所を決定することに重点を置いています。

ロットに対してdigを定義する必要はなく、適切なステップに正規化するだけでよい。
   lot = NormalizeDouble( lot / lot_step, 0 ) * lot_step;
   if ( lot < lot_min ) lot = lot_min;
   if ( lot > lot_max ) lot = lot_max;


ロット変数に取引要求を出しても、ゴミ(小数点以下2桁)になり、端末自体で拒否されます。

少なくとも、このデザインを数年間使っていて、問題が起きたことはありません。


そして、再保険する場合は、小数点以下8桁まで正規化することができます(積立金あり)。「正しい」正規化の後にゴミが出れば、もっと遠くなります。

Документация по MQL5: Стандартные константы, перечисления и структуры / Структуры данных / Структура торгового запроса
Документация по MQL5: Стандартные константы, перечисления и структуры / Структуры данных / Структура торгового запроса
  • www.mql5.com
Стандартные константы, перечисления и структуры / Структуры данных / Структура торгового запроса - Документация по MQL5