どんな新人の質問でも、フォーラムを乱雑にしないように。プロフェッショナルは、通り過ぎないでください。Nowhere without you - 6. - ページ 739

 
korobok777:
Lot=NormalizeDouble(Balance*0.001,2);
 
Vinin:
何か間違ったことを書いている。

はい、誤字です、訂正しました。それとも原理が間違っているのでしょうか?ポイントは、残高を余すことなく10で割った場合、初期ロットに残高の1/10を乗せた積としてロットを取るということでした。そうでしょう?では、どのように?


Vadimはここでもっとシンプルに書いていますが、そうです )))

 
evillive:

はい、誤字です、訂正しました。それとも原理が間違っているのでしょうか?ポイントは、残高を余すことなく10で割った場合、初期ロットに残高の1/10を乗せた積としてロットを取るということでした。そうでしょう?では、どのようにするのですか?


Vadimはここでもっとシンプルに書いていますが、そうです )))

10で割って余りが出ることは、ごくまれです。その他の場合(ほとんどの場合)には、デフォルトのロットがあります。
 
evillive:
double StartLot=0.01;
if(MathMod(AccountBalance(),10)==0) Lot=StartLot*AccountBalance()/10;

そして、MarketInfo()は?

で、mode_minlot, mode_maxlot, mode_lotstep?

やはり、ロット値の許容桁数グリッドに入る必要があります。

#property strict

/******************************************************************************/
double getLot(double factor = 0.001) {
  double minLot = MarketInfo(Symbol(), MODE_MINLOT);

  if (minLot > 0) { // Проверка значения от функции MetaQuotes на вменяемость
    double maxLot = MarketInfo(Symbol(), MODE_MAXLOT);

    if (maxLot >= minLot) { // Проверка второго значения от функции MetaQuotes на вменяемость
      double lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);

      if (lotStep > 0) { // Проверка третьего значения от функции MetaQuotes на вменяемость
        double rawLot = AccountBalance() * factor; // Грубо вычисленное значение лота

        // В процессе "рихтования" грубо вычисленного значения лота подразумевается, что "округление" происходит всегда к меньшему
        if (rawLot >= minLot && rawLot < maxLot + lotStep) { // Если грубо вычисленное значение "влезает" в диапазон разрешённых значений лотов
          int stepNum = int((rawLot - minLot) / lotStep); // Количество step'ов, которое надо "отступить вправо на числовой оси" от минимального значения лота (при преобразовании double -> int как раз и происходит нужный тип округления)

          return minLot + lotStep * stepNum; // Вычисляем значение лота в "разрядной сетке" разрешённых лотов.
        }
      }
    }
  }

  return 0; // Какие-то обстоятельства не позволили выдать значение в "разрядной сетке" разрешённых лотов; для индикации данного события выдаётся специальное значение 0.
}

/******************************************************************************/
void OnStart() {
  Print("AccountBalance() = ", AccountBalance(), ", getLot() = ", getLot());
}

実行したところ、真実に近いものが得られました。

0       20:09:49.699    Script 3 EURUSDm,H1: loaded successfully
0       20:09:49.699    3 EURUSDm,H1: initialized
0       20:09:49.699    3 EURUSDm,H1: AccountBalance() = 152.82, getLot() = 0.15
0       20:09:49.699    3 EURUSDm,H1: uninit reason 0
0       20:09:49.699    Script 3 EURUSDm,H1: removed

エラーはない、と思う。

 
simpleton:

そして、MarketInfo()は?

で、mode_minlot, mode_maxlot, mode_lotstep?

やはり、ロット値の許容桁数グリッドに入る必要があります。

実行し、真実に近いものを得た。

間違えてはいないようです。

ありがとうございます、すでに説明されています :D

自分としては、すべてのチェックで書くのは当然として、ロットをバランス/10比に持っていく方法のアウトラインがあっただけで、そのアイデアは失敗だった......ということがよくわかります。

でも、文字数が多いんだから、もっとシンプルでいいんじゃない?

  lotstep= MarketInfo(Symbol(),MODE_LOTSTEP);
  lotmax=MarketInfo(Symbol(), MODE_MAXLOT);
  lotmin=MarketInfo(Symbol(), MODE_MINLOT);

lot=lotstep*MathRound(AccountBalance()*0.001/lotstep);
if(lot < lotmin) lot = lotmin;
if(lot > lotmax) lot = lotmax;
 
simpleton:

そして、MarketInfo()は?

で、mode_minlot, mode_maxlot, mode_lotstep?

やはり、ロット値の許容桁数グリッドに入る必要があります。

実行したところ、真実に近いものが得られました。

間違えようがないようです。

なぜ、天性のプログラマーが仕事を引き受けると、目標達成のために必要な1行が、半キロに及ぶ羅列になってしまうのだろうか。

double Lot = NormalizeDouble(AccountBalance()/1000,2);
if(Lot<Min_Lot)Lot=Min_Lot;
 
_new-rena:

なぜ、天性のプログラマーが仕事を引き受けると、目標達成のために必要な1行のコードが、半キロに及ぶ羅列になってしまうのだろう。

0.01ではなく、例えば0.03や0.1といったロットステップを持っている人もいます。では、どのように?チェックはすべてのケースで必要です、善は急げです。
 
evillive:
0.01のロットステップではなく、例えば0.03という人もいます。では、どのように?チェックはすべてのケースで必要であり、それほど時間はかからない。
イナイトに(以下略)を設定すれば、もうサーバーやパソコンを煩わせることはありません
double Min_Lot=MarketInfo(Symbol(), MODE_MINLOT);
 
ミニロットじゃなくてピッチの話だけど、まあいいや、忘れてくれ。
 
_new-rena:

なぜ、天性のプログラマーが仕事を引き受けると、目標達成のために必要な1行のコードが、半キロに及ぶ羅列になってしまうのだろう。

なぜなら、あらゆる場面であらゆる種類のクソが待ち構えていて、自分の身は自分で守らなければならないからです。自分で守らなければ、非常に低い品質になってしまい、長い目で見れば大きなコストになってしまうこともあります。90%の努力は悪魔からの防御に費やされ、問題の解決に費やされるのは10%に過ぎない。MT4とMQL4+の場合、その比率はさらに非対称になります。

ドキュメントを 読んでいるときからクソが始まる。

Возвращаемое значение

Информация о финансовом инструменте. Часть информации о текущем финансовом инструменте хранится в предопределенных переменных.

すべてです。金融商品に関する情報を返す義務があり、それ以外の情報は返さない。それ以外の成果はありません。楽器に関する情報を取得します。

#property strict

/******************************************************************************/
void OnStart() {
  Print("MarketInfo(\"Фигня\", MODE_MINLOT) = ", MarketInfo("Фигня", MODE_MINLOT));
  Print("MarketInfo(\"Фигня\", MODE_MAXLOT) = ", MarketInfo("Фигня", MODE_MAXLOT));
  Print("MarketInfo(\"Фигня\", MODE_LOTSTEP) = ", MarketInfo("Фигня", MODE_LOTSTEP));
}

このツールのロットパラメータがどのようなものかを見てみましょう。

0       21:12:18.980    Script 3 EURUSDm,H1: loaded successfully
0       21:12:18.980    3 EURUSDm,H1: initialized
0       21:12:18.980    3 EURUSDm,H1: MarketInfo("Фигня", MODE_MINLOT) = 0.0
0       21:12:18.980    3 EURUSDm,H1: MarketInfo("Фигня", MODE_MAXLOT) = 0.0
0       21:12:18.980    3 EURUSDm,H1: MarketInfo("Фигня", MODE_LOTSTEP) = 0.0
0       21:12:18.980    3 EURUSDm,H1: uninit reason 0
0       21:12:18.980    Script 3 EURUSDm,H1: removed

興味深いパラメータがあります。なぜドキュメントにこの関数のエラー時の動作が書かれていないのかわからない。この関数の挙動を観察してわかった文書化されていない機能を使うことになる。

そのため、MarketInfo()関数は、本来0と異なる値でなければならないこれらの要求パラメータに対して0を返す場合があり、これは文書化されていないエラー状況です。コードは、各パラメータを要求する際にエラーが発生したかどうかをチェックしなければならない。このため、コード内に3つのチェックを設けています。

次のページ明らかに、計算された敷地面積は、許容される敷地面積の範囲に収まらない場合があります。確認しないでおこうか?それとも、「成り行き」ではなく、この状況を明示的にプログラムし、それに対する反応を上位のコードでプログラムすべきなのでしょうか?すべてがプログラムされているわけではなく、それ自体で起こるように動作するときにどのように見えるかの例として、MT4の別の新鮮なリリースでは、何かがどこかに移動し、どこかで奇跡的に不具合が生じ、どこかで完全に動作しなくなったときがあります。もしかしたら、これは望んでいた結果ではないのでしょうか?

コードを展開し、コメントアウトすることで、思考過程や使用した計算モデルを確認できるようにしています。MetaQuotesが設定するロットモデルは、MINLOT、MAXLOT、LOTSTEPのパラメータで定義される「スプレッド注文値グリッド」の形で実装されているため、その用語でロットの正確な値を計算する方が合理的でしょう。だから、計算モデルはそういう言葉で書かれているんです。

半キロメートル」などは見当たりませんね。ただ、関数を一度呼び出して、その結果を変数に格納し、その返り値がエラーでなく、まだ計算を続けることに意味があると判明したときに、もう一度チェックしてから、それぞれの呼び出しを実行するというスタイルで、最大のパフォーマンスを達成するためのコードが実行されます。エラーが発生したことが明らかになれば、無駄な呼び出しで計算資源を浪費することはなくなる。

もっとコンパクトにするには、3つの値を一度に取得し、3つの条件を1つのifでチェックすればよいのです。しかし、最初の呼び出しでエラーが発生した場合、残りの2回の呼び出しは計算資源の無駄遣いになってしまう。

なお、lotStepによる除算を使う式をプログラムするときは、lotStepの値が0と異なることをチェックするだけのifの下で使われていること、つまり、0による除算は起こり得ないことに、あえて注意を払った。原理的には、すべての変数を「double」「int」「const double」「const int」と宣言することで、さらに起こりうるコードの修正時に自分自身を保護し、コードを改善することが可能です。特に、ifのコードで、lotStep変数の値が0と異なるかどうかをチェックしただけなのに、この場所に新たに追加されたコードで、誤ってこの変数に0を代入してしまうと、さらに式に0による除算が発生してしまいます。 もし、この変数がconst doubleと宣言されていれば、コンパイラは直ちに、不正なlotStep変数の変更を報告して、こうした誤りを防いでくれると思うのですけれどね。

つまり、「半キロ」は厳しい客観的条件によるものであり、誰かの気まぐれではないのです。

支店の名称は?まあ、手伝うならちゃんとやれよ、本当に勉強になるようにな。