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

 
enum EAct{PUSH,POP};

template<typename T>
void TempCondition(T &value,EAct act){
   static T temp=T();
   switch(act){
      case PUSH: temp=value; break;
      case POP: value=temp;
   }
}

#define  sortArray(_lArray,_lField) do {                     \
   for(int i = 0; i < ArraySize(_lArray); i++) {            \
      TempCondition(_lArray[i],PUSH);                       \
      for(int a = 1; a <= i; a++) {                         \
         if(_lArray[i]._lField < _lArray[a - 1]._lField){   \
            for(int b = i; b >= a; b--) {                   \
               _lArray[b] = _lArray[b - 1];                 \
               }                                            \
               TempCondition(_lArray[a - 1],POP);           \
               break;}}}} while(false)


struct STest{
   double a;
   int b;
};

void OnStart()
{
    STest test[700];
    sortArray(test,a);
}

它应该是有效的。但我不建议这样做)。

 
Koldun Zloy:

这实际上是最佳状态。而且它允许你设置更复杂的排序条件。

比如说。

是的,而且反正也没有其他解决办法。

模式的要点是要有普遍性。如果你在你的例子中传递另一个结构,而这个结构不包含至少一个字段a,b,c,它将不会被编译。也就是说,该函数不能同时处理两种不同的数据类型

 
 

关于交易、自动交易系统和测试交易策略的论坛

交易的控制板。需要mql5帮助

Vladimir Karputov, 2020.08.18 09:04

这段代码不会起作用--你不能比较糍粑和 方块

   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      ulong OrderTicket=OrderGetTicket(i);
      if(OrderTicket>0 && PositionSelectByTicket(OrderTicket))
        {
         // Stop long позиции------------------------------------------
         if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
           {
            int cur_tr; //трейлинг
            double ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
            double newSl = ask - cur_tr*_Point;
            double positionSl = PositionGetDouble(POSITION_SL);
            double positionTP = PositionGetDouble(POSITION_TP);
            if(newSl > positionSl || positionSl == 0)
              {
               CTrade trade;
               trade.PositionModify(OrderTicket,newSl,positionTP);
              }
           }
        }
     }

如果挂单被部分执行并产生了头寸,该条件将起作用。那么一个订单和一个具有相同票据的头寸将同时存在。

由于这个原因,下面的结构在某些情况下是有意义的。

::PositionSelectByTicket(::OrderGetInteger(ORDER_TICKET))
 
如果您想将所选位置 或订单 MQL数据归零。
PositionSelectByTicket(0); // Обнуляет PositionGet*
OrderSelect(0);            // Обнуляет OrderGet*
 

关于交易、自动交易系统和策略测试的论坛

图书馆: MT4Orders

fxsaber, 2020.08.20 15:44

对于那些使用异步交易的人来说,了解你的账户中可能存在的最大数量的未处理的异步交易的设置将是有用的。

这并不难发现。

Alert: 60 - Too many trade requests


要小心,你可能会遇到一个限制。

 
fxsaber:

雷纳特很早以前就说过,你不仅会被限制住,还可能被直流电挡住。

 
fxsaber:

如果挂单被部分执行并产生头寸,该条件将被触发。那么一个订单和一个具有相同代码的头寸将同时存在。

RannForex-Server 模拟账户中的以下代码可以通过运行该EA立即再现这种情况。

// Воспроизведение ситуации наличия позиции и отложенного ордера с одинаковыми тикетами.

#define  Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)

MqlTradeResult Result = {0};
MqlTradeRequest Request = {0};

int OnInit()
{

        Request.action = TRADE_ACTION_PENDING;
        Request.symbol = _Symbol;
        Request.volume = 100;
        Request.price = Ask;
        Request.type = ORDER_TYPE_BUY_LIMIT;
        
        return(!OrderSend(Request, Result)); // Выставили лимитник по текущей цене.
}

#define  TOSTRING(A) #A + " = " + DoubleToString(A, _Digits)

void OnTradeTransaction( const MqlTradeTransaction&, const MqlTradeRequest&, const MqlTradeResult& )
{
  if (OrderSelect(Result.order) && (OrderGetInteger(ORDER_STATE) == ORDER_STATE_PARTIAL)) // Если наш лимитник исполнился частично
  {
    if (Ask - OrderGetDouble(ORDER_PRICE_OPEN) < 100 * _Point)                            // и находится близко от текущей цены
    {
        Request.action = TRADE_ACTION_MODIFY;
        Request.order = Result.order;
        Request.price = Ask - 1000 * _Point;

      // тогда передвигаем его подальше.
      if (OrderSend(Request, Result)) // Если синхронный OrderSend выполнился успешно, то торговое окружение должно соответствовать.
      {
        // Проверка соответствия торгового окружения.
        if (OrderSelect(Request.order) &&                                                                // Если получилось взять данные нашего ордера
            NormalizeDouble(OrderGetDouble(ORDER_PRICE_OPEN) - Request.price, _Digits))                  // и цена ордера не равна цене успешного OrderSend
          Alert("Bug:" + TOSTRING(OrderGetDouble(ORDER_PRICE_OPEN)) + " != " + TOSTRING(Request.price)); // сообщаем о баге MT5.
      }
    }
    else
      ExpertRemove();
  }     
}


结果。


顺便说一下,该脚本显示(并不总是第一次)在执行同步OrderSend时有一个错误。

Alert: Bug:OrderGetDouble(ORDER_PRICE_OPEN) = 0.89837 != Request.price = 0.88837

在OrderSend执行了几十/几百毫秒后,订单价格是旧的价格,而不是OrderSend成功下达的价格。


回到相同门票的话题上,我们可以得出一些结论。

  1. 如果部分限价单被挂起,标签 "订单和交易 "将不显示生成的交易。
  2. 在套期保值中,一个订单可以产生多个不同价格的IN交易。其结果将是一个零星的(相对于点)开仓价格。
  3. 你可以关闭已生成的头寸,而不删除部分认沽。但如果在这之后,挂单被触发,那么交易将被打开,票据等于之前被关闭的仓位的票据。也就是说,可能会有这样一种情况,你用某张票平仓。然后,一个仓位重新出现在相同的股票上。
  4. 部分执行可能以不同的方式实施,这取决于经纪人的软件。以上是一个标准的MT5实现。

如果有人设法在其他交易服务器上重现这个问题,请分享其名称。

搜索字符串:Oshibka 010。

 
fxsaber:


  1. 你可以关闭生成的头寸,而不删除部分认沽。但如果在这之后,挂单被触发,它将打开一个交易,票据等于之前平仓的票据。也就是说,可能会有这样一种情况,你用某张票平仓。然后一个职位又出现了同样的票。

不是唯一的票吗?这怎么可能呢?

订单和交易都有唯一的票吗?

 
Andrey Khatimlianskii:

不是唯一的票吗?这怎么可能呢?

可以找到的解释是,只要有开仓单,就一定会有仓位。而这个职位有一张独特的门票。那么,在这种原因的对冲中,很有可能在相应的进场和出场交易之后,同一仓位上会出现进场触发。

订单和交易甚至有独特的门票吗?

他们是独一无二的。但当然,ORDER_TICKET可以等于DEAL_TICKET。