エキスパート: トレーダーのためのMQL5プログラミング - 書籍からのソースコード。第7部

 

トレーダーのためのMQL5プログラミング - 書籍からのソースコード。第7部:

本書最後となる第7部では、MetaTrader 5のプログラムを開発する際に役立つMQL5 APIの高度な機能について説明します。これには、カスタム金融銘柄、組み込みの経済指標カレンダーイベント、およびネットワーキング、データベース、暗号化などの汎用テクノロジーが含まれます。

トレーダーのためのMQL5プログラミング - 書籍からのソースコード。第7部

作者: MetaQuotes

 
優れた学習リソース
 
学ぶ
 
カレンダーキャッシュと フィルターに関する 小さなバグフィックスと改善です。
MQL5 Book: Advanced language tools / Economic calendar / Transferring calendar database to tester
MQL5 Book: Advanced language tools / Economic calendar / Transferring calendar database to tester
  • www.mql5.com
The calendar is available for MQL programs only online, and therefore testing news trading strategies poses some difficulties. One of the solutions...
ファイル:
 

これはエラーなのでしょうか、それとも私の理解不足なのでしょうか?

MarginProfitMeter.mqhファイルです。

// 「現在」の金額を「口座」の金額に変換する
bool Convert(const string current, const string account,
             const bool ask, double &margin, const datetime moment = 0)
  {
   string rate;
   int dir = FindExchangeRate(current, account, rate);
   if(dir == +1)
     {
      margin *= moment == 0 ?
                SymbolInfoDouble(rate, ask ? SYMBOL_BID : SYMBOL_ASK) :
                GetHistoricPrice(rate, moment, ask);
     }
   else
      if(dir == -1)
        {
         margin /= moment == 0 ?
                   SymbolInfoDouble(rate, ask ? SYMBOL_ASK : SYMBOL_BID) :
                   GetHistoricPrice(rate, moment, ask);
        }
      else
        {
         static bool once = false;
         if(!once)
           {
            Print("Can't convert ", current, " -> ", account);
            once = true;
           }
        }
   return true;
  }

ゼロで割ることは不可能ですよね?


また、このメソッドはマージンを返すべきですが、価格を返しています。どこかでこの価格に約定 サイズを乗じる必要があるのは理解できますが、どこでそれをするのが正しいのか理解できません。

この関数の中で追加すればいいのでしょうか、それともどこからこの関数を呼び出せばいいのでしょうか?

 
Aleksandr Slavskii #:

これが間違いなのか、それとも私が何かを見落としているのか、教えていただけますか?

ファイル MarginProfitMeter.mqh

ゼロで割ることは不可能ですよね?

はい、できません。

margin /= moment == 0 ?
                   SymbolInfoDouble(rate, ask ? SYMBOL_ASK : SYMBOL_BID) :
                   GetHistoricPrice(rate, moment, ask);

除算記号の後に三項演算 子があり、代入"/="が付いています。だから、もしmomet==0なら

margin /= SymbolInfoDouble(rate, ask ? SYMBOL_ASK : SYMBOL_BID)

となります:

margin /= GetHistoricPrice(rate, moment, ask)

しかし、私なら両方の関数からゼロのチェックを加えます。


また、このメソッドはマージンを返すべきですが、価格を返しています。どこかでこの価格に約定サイズを掛け合わせる必要があるのはわかるのですが、どこをどうするのが正しいのかがわかりません...。

説明から判断すると

// 「現在」の金額を「口座」の金額に変換する

このメソッドは、現在のお金(通貨)を保証金のお金(通貨)に変換します。そしてコードから判断すると、このメソッドは証拠金を保証金の通貨に変換します。

成功すれば、メソッドはtrueを返します。また、補正された新しい証拠金額を計算し、margin変数に格納します。これはリンクのパラメータです:

double &margin

つまり、計算の結果としてそれを得ることができます。

 
Denis Kirichenko #:

本当にできない。

除算記号の後に三項演算 子があり、代入"/="がついている。つまり、momet==0なら

そう、三項演算子だ。今朝は疲れた、頭が悪くなりそうだ。


デニス・キリチェンコ

説明から判断すると

メソッドは現在のお金(通貨)を預金(通貨)に変換します。そしてコードから判断すると、このメソッドは証拠金を預金通貨に変換します。

いいえ、それも正しいです。


申し訳ありません、コードを少し間違えてしまいました。


というのも、出来高が3枚を超えると、結局は証拠金の数え方が間違ってしまうからです。

EURUSD; margin = 24668.8  //  OrderCalcMargin()
EURUSD; margin = 10889.599999999999 // MarginProfitMeter.mqh 

10枚の証拠金計算

 
Denis Kirichenko #:
margin /=moment ==0? SymbolInfoDouble(rate, ask ?SYMBOL_ASK:SYMBOL_BID) GetHistoricPrice(rate, moment, ask);

少し間違っている。条件(margin /= moment)==0、そして三項演算子...

 
Alexey Viktorov #:

少し間違っている。マージン/=モーメント)=0という条件と、三項演算子...

なんとなく納得できない。まずこの条件を満たしてみて ください:

double margin = 1.5;
datetime moment = 0;
margin /= moment;

それではハリネズミとハリネズミを分けていることになり、それ自体が疑問です。

また、代入演算の優先順位は非常に低く、zptだけが優先順位が低い。

コンパイラも怒ります:

possible loss of data due to type conversion from 'datetime' to 'double'

そして関数のロジックはマージン変換です。私が理解する限り、moment = 0はnowである:

margin /= moment == 0 ?
                SymbolInfoDouble(rate, ask ? SYMBOL_ASK : SYMBOL_BID) :
                GetHistoricPrice(rate, moment, ask);

というのは、 なら現在の価格を求める。過去 あれば、過去の価格を参照する。そして、希望する価格を手に入れたら、最後に、マージン額をこの価格で割って代入する......。そして、あなたのロジックでは、moment = 0では、マージン換算ではなく、市場価格か過去の価格しか得られないことがわかります。


一般的に、教科書には括弧書きで 書いた方が良いと思います:

margin /= (moment == 0) ?
                   SymbolInfoDouble(rate, ask ? SYMBOL_ASK : SYMBOL_BID) :
                   GetHistoricPrice(rate, moment, ask);
 
Denis Kirichenko #:

なんとなく納得できない。まずはその条件を満たしてみて ください:

これではハリネズミをハリネズミに分けることになるが、それ自体がすでに疑わしい。

そして、割り当てオペレーションの優先順位は非常に低く、zptだけが優先順位が低い。

そしてコンパイラも怒る:

そして、関数のロジックはマージン変換である。私が理解する限り、moment = 0は今です。 では:

というのは、現在 であれば現在の価格を求めます。過去 あれば、過去の価格を参照する。そして、希望する価格を手に入れたら、最後に、マージン額をこの価格で割って代入する......。そして、あなたのロジックでは、もしmoment = 0であれば、マージン換算ではなく、市場価格か過去の価格しか得られないことがわかります。


一般的に、教科書には括弧書きで 書いた方が良いと思います:

納得。そうですね、不注意でした。しかし、教科書用に、私にも理解できるように書くのであれば、こう書くのがいいだろう。

margin /= ( moment == 0 ?
                   SymbolInfoDouble(rate, ask ? SYMBOL_ASK : SYMBOL_BID) :
                   GetHistoricPrice(rate, moment, ask));