mql5言語の特徴、微妙なニュアンスとテクニック - ページ 169

 

ちなみに、Assertのアナログは

#define  ASSERT (STD_CAssert(__LINE__,__FUNCTION__)).Assert

class STD_CAssert{
   string function;
   int line;
public:
   STD_CAssert(int _line,string _func):line(_line),function(_func){}
   void Assert(bool condition,string text=NULL);
  };
//--------------------------------------------------------------------------
void STD_CAssert::Assert(bool condition,string reason=NULL){
   if (condition) return;
   Alert(StringFormat("Assert in line %i, function %s.\nReason: %s.",line,function,reason==NULL||reason==""?"Unknow":reason));
   int a=0;
   int b=1/a;}

void OnStart()
{
   Test();
}

void Test(){
   ASSERT(2==3,"Some reason");
}
 
Igor Makanu:

必要なのか?

もし、開発者がexit/abortを標準装備していれば、例えば、TFの準備ができていない場合、データ処理を正しく終了させることが可能です - OHLCデータ、サーバーへの注文送信処理にも有効でしょう...OnTick()の終了にreturn()を使わずに、任意の場所でコードを中断して次のtickの前に終了できると便利なのですが...。

実は松葉杖の実装は可能なのですが、そこはユーザビリティが悪いので、動くはずなのですが見せもしません。
 

使い勝手は向上しているようですが。一般に、ネストされた関数を含め、出力可能なすべての関数 またはメソッドコールは、_call マクロでラップする必要があります。興味のある方は、全ハンドラ用に残りを自由に書いてみてください。それは、あるアイデアのテストとして、クランク上に書かれたもので、言葉からして、全くテストされていないのです。

#ifdef _DEBUG
   #define  DELETE(dObj) do if (CheckPointer(dObj)!=POINTER_INVALID) {delete dObj; dObj=NULL;} while(false)
#else
   #define  DELETE(dObj) do {delete dObj; dObj=NULL;} while(false)
#endif

#define  START  class STD_CStart; void OnStart(){std_start=new STD_CStart; std_start.Main(); DELETE(std_start);}
#define  ON_START  START\
static STD_CStart* std_start=NULL;  \
class STD_CStart{   \
public: void Main();   \
};                \
void STD_CStart::Main

#define  DELETE_EVENTS do if (std_start!=NULL) DELETE(std_start); while(false)
#define  EXIT(out) do {DELETE_EVENTS; return out;} while(false)
#define  CHECK(out) do if (!std_start) EXIT(out); while(false)
#define _call(funk,out) do {funk;CHECK(out);} while(false)

ON_START()
{
   int x=0;
   Print("Start");
   _call(TestInt(4),);
   Print(++x);
   _call(TestInt(1),);
   Print(++x);
   _call(TestInt(6),);
   Print(++x);
   TestVoid();   
}

int TestInt(int a){
   static int x=0;
   Print("Func call ",++x);
   if (a<3) EXIT(NULL);
   return 0;
}

void TestVoid(){
   Print("Error");}
 

MT5には、誤って端末を閉じて しまうことに対する保護機能はありません。最近、そんなシナリオがあったんです。

  • 端末とブラウザは全画面で表示されます。ブラウザで見ています。
  • ブラウザがフリーズしているので、右上の十字架をクリックする。
  • 閉まらないので、さらに数回押してみる。
  • 押している途中で、ブラウザが終了し、ウィンドウが消えてしまう。そしてこの時、カーソルの下にある端末の十字が、私が押した場所です。
  • 端末が閉まるのが、あまりにも早いので、気づかないだけなのです。特に、多くのターミナルが開いているとき。

これは、例えばバッチ最適化などの際に非常に不愉快な状況です。しかし、バトルアドバイザーの場合はもっとひどい。バトルターミナルを殺してしまったことに気づかないのはバカかもしれません。


そんなプロテクトを施しているんですね。

void OnDeinit( const int Reason )
{
  if (Reason == REASON_CLOSE)
    MessageBox("Terminal is being closed!");
}

閉じるときに、5秒間メッセージが表示されます。だから、何が本当に起こったのかを把握することができるのです。端末にプロテクトがないのはおかしい。

 
fxsaber:

MT5には、誤って端末を閉じてしまうことに対する保護機能はありません。最近、そんなシナリオがありました。

  • 端末とブラウザは全画面で表示されます。ブラウザで見ています。
  • ブラウザがフリーズしているので、右上の十字架をクリックする。
  • 閉まらないので、さらに数回押してみる。
  • 押している途中で、ブラウザが終了し、ウィンドウが消えてしまう。そしてこの時、カーソルの下にある端末の十字が、私が押した場所です。
  • 端末が閉まるのが、あまりにも早いので、気づかないだけなのです。特に、多くのターミナルが開いているとき。

これは、例えばバッチ最適化などの際に非常に不都合な状況です。しかし、バトルアドバイザーの場合はもっとひどい。バトルターミナルを殺してしまったことに気づかないのはバカかもしれません。


そんなプロテクトを施しているんですね。

閉じるときに、5秒間メッセージが表示されます。だから、何が本当に起こったのかを把握することができるのです。ターミナルにプロテクトがないのはおかしい。

もっとシンプルな選択肢もある。

  1. コンバットターミナルを最小化する。
  2. VPSに戦闘端末を置く
  3. いたずらな手を縛って、パソコンに近づかない。)))
  4. 考えないと、何か出てくるかも・・・))
 
Alexey Viktorov:

もっとシンプルな選択肢もある。

  1. バトルターミナルを最小化しておく。
  2. VPSで戦闘端末を保持
  3. いたずらな手を縛って、パソコンに近づかない。)))
  4. 考えないと、何か出てくるかも・・・)))

オンVPSも 終了する可能性があります。そこで専門家がプッシュを送信しています。

それに、風のインターフェイスが遅くなると、間違ったクロスを打つのは本当に簡単なんです。私はそれをやった、今私はコンテキストメニューのタスクバーでそれを閉じます。

 
Alexey Viktorov:

もっと簡単な方法があります。

デスクトップマネージャーをインストールし、1つのデスクトップをブラウザなどに充て、もう1つのデスクトップを端末に充てます。

またはLinuxをインストール(デスクトップマネージャーが付属しています :)

 
Vladimir Simakov:

ちなみに、Assertのアナログは

mqlステートメントの実装では、デバッグモードのためにDebugBreak関 数を使用することは理にかなっています。デバッグが非常に楽になり、クラッシュアウトするよりもずっと便利です。
 

トレーディング、自動売買システム、ストラテジーテストに関するフォーラム

ライブラリ:MT4Orders

fxsaber, 2020.04.07 18:47

MT5では、部分実行が非常に見つけやすい。
// true - сделка в результате частичного исполнения.
bool IsPartial( const ulong TicketDeal )
{
  const ulong TicketOrder = HistoryDealGetInteger(TicketDeal, DEAL_ORDER);
  
  return((HistoryDealGetInteger(TicketDeal, DEAL_TYPE) <= DEAL_TYPE_SELL) &&
         (!TicketOrder ||
          (HistoryDealGetDouble(TicketDeal, DEAL_VOLUME) != HistoryOrderGetDouble(TicketOrder, ORDER_VOLUME_INITIAL))));
}
 

ヘッジでは、1つのポジションが複数のINトレードで構成されることがあります。これは、部分実行によって行われます。

この場合、部分約定した注文は、ORDER_TIME_SETUP(_MSC)が最初の(場合によっては最後の)取引の時刻に変更されます。つまり、例えばBuyLimitがいつ置かれたかを履歴から判断することは不可能である。


その結果、ヘッジのポジションは、ネッティングでよく見られるように、始値が端数になってしまうことがあります。

理由: