mql5语言的特点、微妙之处以及技巧 - 页 169

 

顺便说一下,断言的类似物是

#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:

也就是说,它正是我所需要的!

如果开发人员将退出/终止作为标准,那么就有可能正确地终止数据处理,例如,如果TF没有准备好--OHLC数据,它对处理发送到服务器的订单也是有用的。如果能在任何地方中断代码,并在下一个tick之前退出,而不需要无休止的return()来退出OnTick(),那就很方便了。

实际上可以实现一个拐杖,但那里的可用性很差,我甚至不会给你看,尽管它应该可以工作。
 

尽管可用性似乎得到了改善。一般来说,每个可能有输出的函数 或方法调用,包括嵌套函数,都应该用_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. 绑好你的淘气的手,远离你的电脑。)))

在VPS上 也可能关闭。我有专家在那里发推。

而且,当风向界面变慢时,真的很容易打错十字。我已经做了,现在我在任务栏的上下文菜单中关闭它。

[删除]  
Alexey Viktorov:

有几个更容易的选择。

安装一个桌面管理器,将一个桌面专用于浏览器和东西,将另一个桌面专用于终端。

或者安装Linux(桌面管理器自带:))。

 
Vladimir Simakov:

顺便说一下,断言的类似物是

对于任何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))));
}
 

在套期保值中,一个头寸可以由几个IN交易组成。这是由部分执行完成的。

在这种情况下,被部分执行的订单将改变其ORDER_TIME_SETUP(_MSC)为第一个(可能是倒数第二个)交易的时间。换句话说,不可能从历史记录中确定,例如,BuyLimit是什么时候下的。


因此,套期保值的头寸可以有一个零星的开盘价,这在净值上经常可以看到。