高手来说说,如何实现平仓后就触发另一个函数? - 页 2

 
okwh #:

MT提供的消息 只是一般的交易活动,且优先级不高,大致和计时消息相当,即不是一个消息产生必须响应处理完 才发下各消息, 即发生消息和处理响应消息是异步的、不同步、不必然有序。


因此如果你需要通过comment分析单子之间的关系,应自己 保留 、查找、管理有关关系信息。当然这对编程能力要求较高

参考 https://www.mql5.com/zh/articles/88

我曾经有写过一个在MQL4上模拟MQL5的 OnTrade()函数,即交易事件发生时,它会被触发一次。本想上传到代码库中,无赖不知怎么上传

a

//+------------------------------------------------------------------+
//|                                        OnTradeFunctionInMQL4.mq4 |
//|                        Copyright 2023, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create timer
   EventSetMillisecondTimer(1);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   if(OnTrades())
      printf("%s >有一个交易事件发生!", TimeToString(TimeCurrent(), TIME_DATE | TIME_SECONDS));
  }
//+------------------------------------------------------------------+
bool OnTrades(void)                          // 模拟MQL5 OnTrade()函数的功能
  {
   int           total      = OrdersTotal(); // 更新当前单子总数
   static int    last_total = total;         // 初始化记录最后订单单数
   static double price[];                    // 静态储存所有单子的开仓价,包括挂单
   static double sl[];                       // 静态储存所有单子的止损价,包括挂单
   static double tp[];                       // 静态储存所有单子的止盈价,包括挂单
   static bool   init_data  = true;          // 只运行一次
   if(init_data)                             // 初始化当前数据,第一次加载EA时不运行,只记录数据
     {
      ArrayResize(price, total);             // 格式化数组长度
      ArrayResize(sl, total);                // 格式化数组长度
      ArrayResize(tp, total);                // 格式化数组长度
      for(int i = 0; i < total; i++)         // 记录数据
         if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
           {
            price[i] = OrderOpenPrice();
            sl[i]    = OrderStopLoss();
            tp[i]    = OrderTakeProfit();
           }
      init_data = false;
     }
   else
      if(total != last_total)                 // 单子数量发生改变时,重新记录数据
        {
         ArrayResize(price, total);           // 订单总数增加或减少时,重新格式化数组长度
         ArrayResize(sl, total);              // 订单总数增加或减少时,重新格式化数组长度
         ArrayResize(tp, total);              // 订单总数增加或减少时,重新格式化数组长度
         for(int i = 0; i < total; i++)       // 重新记录
            if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
              {
               price[i] = OrderOpenPrice();
               sl[i]    = OrderStopLoss();
               tp[i]    = OrderTakeProfit();
              }
         last_total = total;                  // 记录最新的单子总数
         return(true);
        }
      else
        {
         // 订单总数没有变化时,检查所有单子的挂单价,止损价,止盈价是否发生变化
         for(int i = 0; i < total; i++)
            if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
               if(OrderOpenPrice() != price[i] ||
                  OrderStopLoss() != sl[i] ||
                  OrderTakeProfit() != tp[i])
                 {
                  price[i] = OrderOpenPrice(); // 有变化,重新写入
                  sl[i]    = OrderStopLoss();  // 有变化,重新写入
                  tp[i]    = OrderTakeProfit();// 有变化,重新写入
                  return(true);
                 }
        }
   return(false);
  }
//+------------------------------------------------------------------+
 
universework #:

很好,试了可以。实际我最终目的是要在检测到出场订单后,要获取这个出场订单对应的in入场订单的comment注释,如何实现?

出场订单的 comment都是空的,所以过滤掉空的,往前遍历就能找到 入场订单的comment注释,但如果同一标的前后入场不同的多个机会, 再往前遍历到入场订单的comment注释就可能与出场订单不是一一对应了,所以如何获取这个出场订单相对应的in入场订单的comment注释?或者如何实现让out出场单子的 comment注释与in 入场订单的 comment注释一致,而不是空?

对于你的问题

1、" 所以如何获取这个出场订单相对应的in入场订单的comment注释?"

你这个问题的话,就不要去获取对应out,因为他in的单子,也会进入这个函数

筛选in类型的,然后通过获取comment就好,

if( entry  == DEAL_ENTRY_IN )
        {
        string comment = HistoryDealGetString(lastDealID,DEAL_COMMENT);
	//相关操作
        }

2、“ 或者如何实现让out出场单子的 comment注释与in 入场订单的 comment注释一致,而不是空?

这个问题,首先如果单子是按你的操作(你自己写的函数)出场,那么你在出场的函数里,把对应的comment填充,在历史记录里面就会显示你填充的

但是如果是系统的出场,例如你设置了止损止盈,强制平仓等,那么他出场注释就会是特定的,这个我觉得应该也可以改,但是还没有发现在哪可以修改

另外,手动是没有注释的

你可以说说你是怎么出场的,或者你说你想用comment做什么操作,然后我们再讨论讨论

 
Mage He #:

对于你的问题

1、" 所以如何获取这个出场订单相对应的in入场订单的comment注释?"

你这个问题的话,就不要去获取对应out,因为他in的单子,也会进入这个函数

筛选in类型的,然后通过获取comment就好,

2、“ 或者如何实现让out出场单子的 comment注释与in 入场订单的 comment注释一致,而不是空?

这个问题,首先如果单子是按你的操作(你自己写的函数)出场,那么你在出场的函数里,把对应的comment填充,在历史记录里面就会显示你填充的

但是如果是系统的出场,例如你设置了止损止盈,强制平仓等,那么他出场注释就会是特定的,这个我觉得应该也可以改,但是还没有发现在哪可以修改

另外,手动是没有注释的

你可以说说你是怎么出场的,或者你说你想用comment做什么操作,然后我们再讨论讨论


订单是设定止损止盈的,所以是系统出场,注释是特定的,

我获取out对应的in的订单的comment,是为了实现撤掉与in订单的comment一样的挂单。策略涉及多个挂单,每个挂单的comment的主要内容是一致的。当第一个挂单成交后变成了持仓,历史记录中就能获取in对应的comment,等到这第一个挂单止盈,就要求剩下的几个挂单全撤掉。所以如果筛选in类型的订单,通过获取in订单的comment来撤掉对应comment一致的挂单,但实际这第一个订单还没止盈,剩下的几个挂单就被全撤了,不符合策略要求。所以要求获取in订单平仓后再获取到他的 comment,也就是获取out对应in订单的 comment,来触发撤单行为,再来讨论下

 
Zhang Yi #:

你搞错了,这里的 ticket 指的是正在交易中执仓的订单编号(即你想要平仓的订单编号,具体如何在EA中用代码获取,我就不写了)

例如,我想平仓订单编号为 15338917的单子

这样可以获取和它对应in的注释

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

如果你的目的是手动平仓,那么此时我们就需要用到这个系统函数了,即交易事件发生时

具体方法代码如下:

这些都是很简单的方式方法,没必要搞复杂了。如果你看不懂我也没办法,我的目的不是教人,我只是帮忙你解决问题,不喜勿喷。。。
Zhang Yi #:

你搞错了,这里的 ticket 指的是正在交易中执仓的订单编号(即你想要平仓的订单编号,具体如何在EA中用代码获取,我就不写了)

例如,我想平仓订单编号为 15338917的单子

这样可以获取和它对应in的注释

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

如果你的目的是手动平仓,那么此时我们就需要用到这个系统函数了,即交易事件发生时

具体方法代码如下:

这些都是很简单的方式方法,没必要搞复杂了。如果你看不懂我也没办法,我的目的不是教人,我只是帮忙你解决问题,不喜勿喷。。。

策略要求是系统平仓出场,非手动,就是默认的止损止盈出场,你这里是检测持仓comment,

实际我获取out对应的in的订单的comment,是为了实现撤掉与in订单的comment一样的挂单。策略涉及多个挂单,每个挂单的comment的主要内容是一致的。当第一个挂单成交后变成了持仓,历史记录中就能获取in对应的comment,等到这第一个挂单止盈,就要求剩下的几个挂单全撤掉。所以要求获取in订单平仓后再获取到他的 comment,也就是获取out对应in订单的 comment,来触发撤单行为,再来讨论下

 

策略要求是系统平仓出场,非手动,就是默认的止损止盈出场 

实际我获取out对应的in的订单的comment,是为了实现撤掉与in订单的comment一样的挂单。策略涉及多个挂单,每个挂单的comment的主要内容是一致的。当第一个挂单成交后变成了持仓,历史记录中就能获取in对应的comment,等到这第一个挂单止盈,就要求剩下的几个挂单全撤掉。所以要求获取in订单平仓后再获取到他的 comment,也就是获取out对应in订单的 comment,来触发撤单行为,如果一个机会只在一个级别有挂单,很容易处理,如果多个级别都有机会,撤单如何实现?再来讨论下

 
Zhang Yi #:

可能你们把问题想复杂了,如果你只是单纯的想获取out(平仓)类型单子和它对应in(开仓)类型单子的注释, 那么这个就比较简单,无需用到 OnTradeTransaction() 或者  OnTrade()函数了。

首先,你先要知道你将要平仓的执仓订单编号,进行平仓操作(具体如何获取,这里就不详细说明了,我相信方法你应该会)

不喜勿喷^_^


求教1

程序本来是KDJ指标,然后我加了下面代码意图实现当J线死叉的时候,发出预警信号,但总是没收到预警信息,测试也没任何错误提示,求大神看看问题在哪里?谢谢

for(int j=10;j<limit;j++)

   {

     if((JBuffer[j-1] > KBuffer[j-1])&&(JBuffer[j] < KBuffer[j])) //判断两线产生了死叉

      {

     

       if(j==prev_calculated)//只针对当前K线报警历史K线就不用报警了

          {

           Alert("UP");

           SendMail("eurusd","死叉");

           SendNotification("空平");

          }//预警

      }

原因: