程序库: MT4Orders - 页 33

 
fxsaber:

所有更改都写在页眉中。

是的,但你看不到是什么。等我改好了再给你看。


fxsaber:

ZY 在 KB 中查看了我的作品...最好忘掉 zip。

没错。zip 不会更新 (

 
// 更改列表:
// 08.02.2019
// 添加:通过 OrderClose 部分平仓时,将保存仓位注释。
// 如果需要在部分平仓时更改未结头寸的注释,可在 OrderClose 中进行设置。
 

有些任务仅靠 MQL4 无法解决。

但 MT4 风格和 MT5 风格可以并行使用。下面是这种组合的一个例子。

交易、自动交易系统和交易策略测试论坛。

OnTradeTransaction 交易处理

fxsaber, 2019.02.08 12:37 pm.

任务

挂单被置于净价(Netting)上(可以是多方向的,每种类型的数量不限)。有必要在原始挂单每次触发时,以止损/限价挂单的形式下达其 SL/TP 订单。在这种情况下,SL/TP 订单应相互依赖:如果一个订单触发,第二个订单将被删除。初始挂单和止损/限价挂单可以部分触发。Expert Advisor 可随时重新加载,包括转移到另一个终端。


解决方案

#include <MT4Orders.mqh> //https://www.mql5.com/zh/code/16006

input int inTP = 100;
input int inSL = 200;
sinput MAGIC_TYPE inMagicNumber = 0;
sinput string inStrKey = "SLTP";

int GetAmountDeals()
{
  return(HistorySelect(0, INT_MAX) ? HistoryDealsTotal() : 0);
}

bool IsMyString( const string Str, const string Key )
{
  return(StringSubstr(Str, 0, StringLen(Key)) == Key);
}

string ToMyString( const string Str, const string Key )
{
  return(Key + Str);
}

struct ORDER
{
  int Type;
  TICKET_TYPE Ticket;
  double Lots;
  double OpenPrice;
  MAGIC_TYPE Magic;
  string Comment;
  
  ORDER() : Type(OrderType()), Ticket(OrderTicket()), Lots(OrderLots()),
            OpenPrice(OrderOpenPrice()), Magic(OrderMagicNumber()), Comment(OrderComment())
  {
  }
};

#define _CS(A) ((!::IsStopped()) && (A))

bool GetPairOrder()
{
  bool Res = false;

  ORDER Order;
  Order.Type = 6 - Order.Type + ((Order.Type & 1) << 1);
  
  for (int i = OrdersTotal() - 1; _CS((i >= 0) && (!Res)); i--)
    Res = OrderSelect(i, SELECT_BY_POS) && (OrderType() == Order.Type) &&
          (OrderMagicNumber() == Order.Magic) && (OrderComment() == Order.Comment);
    
  return(Res);
}

void CheckSLTP( const string Symb, const MAGIC_TYPE Magic, const string Key, const int Slip = 100 )
{    
  for (int i = OrdersTotal() - 1; _CS(i >= 0); i--)
    if (OrderSelect(i, SELECT_BY_POS) && (OrderType() > OP_SELL)  &&
        (OrderMagicNumber() == Magic) && (OrderSymbol() == Symb) && IsMyString(OrderComment(), Key))
    {
      const ORDER Order;      
      
      if (!_CS(GetPairOrder()))
      {
        OrderDelete(Order.Ticket);
        
        i = OrdersTotal();
      }
      else if (_CS(OrderLots() < Order.Lots))
      {
        if (OrderDelete(Order.Ticket))
          OrderSend(OrderSymbol(), Order.Type, OrderLots(), Order.OpenPrice, Slip, 0, 0, Order.Comment, Order.Magic);
          
        i = OrdersTotal();          
      }
    }
}

void CheckFill( const string Symb, const MAGIC_TYPE Magic, const string Key, const int SL, const int TP )
{    
  static int PrevDeals = GetAmountDeals();
  
  const double point = SymbolInfoDouble(Symb, SYMBOL_POINT);
  const int NewDeals = GetAmountDeals();
  
  while (_CS(PrevDeals < NewDeals))
  {
    const ulong Ticket = HistoryDealGetTicket(PrevDeals);
    
    if (Ticket && (HistoryDealGetInteger(Ticket, DEAL_MAGIC) == Magic) &&
                  (HistoryDealGetString(Ticket, DEAL_SYMBOL) == Symb) &&
                  !IsMyString(HistoryDealGetString(Ticket, DEAL_COMMENT), Key))
    {
      const double Lots = HistoryDealGetDouble(Ticket, DEAL_VOLUME);
      const double Price = HistoryDealGetDouble(Ticket, DEAL_PRICE);
      const int Type = 1 - (int)HistoryDealGetInteger(Ticket, DEAL_TYPE);
      const double Koef = Type ? -point : point;
      const string Comment = ToMyString((string)Ticket, Key);
      
      if (OrderSend(Symb, Type + OP_BUYLIMIT, Lots, Price - Koef * TP, 0, 0, 0, Comment))
        OrderSend(Symb, Type + OP_BUYSTOP, Lots, Price + Koef * SL, 0, 0, 0, Comment);
    }
    
    PrevDeals++;
  }
}

void System()
{
  CheckFill(_Symbol, inMagicNumber, inStrKey, inSL, inTP);
  CheckSLTP(_Symbol, inMagicNumber, inStrKey);
}

void OnTrade()
{
  System();
}

void OnInit()
{
  OnTrade();
}
 

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

库:MT4Orders

fxsaber, 2019.01.13 17:23 PM.

Kim 在 MT4 下的功能颇受欢迎,因此我从他的网站下载了所有源代码,并为它们在 MT5 下编写了一个简单的 "转换器"。
#include <KimIVToMT5.mqh> //https://c.mql5.com/3/263/KimIVToMT5.mqh

#include "e-Trailing.mq4" // http://www.kimiv.ru/index.php?option=com_remository&Itemid=13&func=fileinfo&id=14

void OnTick() { start(); }

结果发现,Kim 的转换器也能让其他一些 MT4 顾问在 MT5 下运行

#include <KimIVToMT5.mqh> //https://c.mql5.com/3/263/KimIVToMT5.mqh

#include "Reaction.mq4"   //https://www.mql5.com/zh/code/24609

void OnTick() { start(); }
 
// 更改列表:
// 20.02.2019
// 修复:如果现有 MT5 交易中没有 MT5 订单,程序库将等待历史同步。如果失败,它将报告相关情况。


在 MT5 上绕过了这一陷阱

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

新版 MetaTrader 5 2005:经济日历、作为服务的 MQL5 程序和 R 语言 API

fxsaber, 2019.02.20 21:06

服务
// 脚本会捕捉历史记录中没有交易订单的情况。

#define _CS(A) ((!::IsStopped()) && (A))
#define  TOSTRING(A) #A + " = " + (string)(A) + " "
#define  OFFSET 100

void OnStart()
{
  datetime PrevTime = OFFSET;
  
  while (_CS(true))
  {
    if (HistorySelect(PrevTime - OFFSET, INT_MAX))
    {
      const int Total = HistoryDealsTotal();
      
      for (int i = 0; _CS(i < Total); i++)
      {
        const ulong DealTicket = HistoryDealGetTicket(i);
        const ulong OrderTicket = HistoryDealGetInteger(DealTicket, DEAL_ORDER);        
        
        int Count = 0;
        const ulong StartTime = GetMicrosecondCount();
        
        while ((HistoryOrderGetInteger(OrderTicket, ORDER_TICKET) != OrderTicket) && !HistoryOrderSelect(OrderTicket)) // 如果没有交易订单
          Count++;
        
        if (Count)
          Alert(TOSTRING(DealTicket) + TOSTRING(OrderTicket) + TOSTRING(Count) + TOSTRING(GetMicrosecondCount() - StartTime)); // 打印出情况
        
        PrevTime = (datetime)HistoryDealGetInteger(DealTicket, DEAL_TIME);
      }
    }
    
    Sleep(0); // 如果不这样做,终端会立即挂起。
  }
}


如果注释掉 Sleep,运行它就会立即杀死终端。但这将与其他事情有关。

事实证明,当历史记录中缺少交易订单 时,很容易捕捉到这种情况:有一笔交易,但没有订单。

脚本在 MQ-Demo 上的结果

Alert: DealTicket = 336236873 OrderTicket = 356249474 Count = 1614408 GetMicrosecondCount()-StartTime = 229880 
Alert: DealTicket = 336236882 OrderTicket = 356249486 Count = 1565921 GetMicrosecondCount()-StartTime = 229998 
Alert: DealTicket = 336236887 OrderTicket = 356249492 Count = 1559345 GetMicrosecondCount()-StartTime = 229788 
Alert: DealTicket = 336236898 OrderTicket = 356249505 Count = 157107 GetMicrosecondCount()-StartTime = 22878 
Alert: DealTicket = 336236901 OrderTicket = 356249508 Count = 1544271 GetMicrosecondCount()-StartTime = 220879 

等待交易订单出现在历史记录中的时间超过 200 毫秒!在这段时间内,无法确定滑点和执行时间等信息。

试想一下,如果您需要一个服务,将平仓数据写入文件。由于该 "功能",根本无法实现。


MT5 的这一架构特性无法以任何方式修正,我说的对吗?


库中考虑到的此类问题难以计数。

 
Andrey Khatimlianskii:

是的,但你看不到它们在什么里面。等我看到了再给你看


没错压缩包没有更新

当你逐个下载文件时,修改日期就会丢失。我必须按大小浏览,但并非所有修复都能改变大小。

我有个建议:

在每个文件的页眉中添加修改日期,可选版本号,可选更改历史。

除了文件外,还可以像有些人那样发布您的 zip/rar。

 
bool IsTradeAllowed(void)
  {
   return(::MQLInfoInteger(::MQL_TRADE_ALLOWED));       //表达式不是布尔型
  }
 
Edgar:

资料库只包含一个文件。其余所有文件都是很久没有更新的小玩意儿。

不过,还有OrderSend_Test2.mq5 - 这是 MT5 和程序库的压力测试。它会向交易服务器发送垃圾邮件,从而切断自动交易。

 

我知道。在这种情况下,是的。但自上次以来,有 3 个文件发生了变化。

我指的是简化版本管理的一般方法。我自己总是在 mqh 标头添加日期,在 mq5 添加日期和版本。

包括我的完整存档(保存修改日期)可以让我不假思索地更新所有内容。
 
Edgar:

我知道。在这种情况下,是的。但自上次以来,有 3 个文件发生了变化。

我指的是简化版本管理的一般方法。我自己总是在 mqh 头添加日期,在 mq5 添加日期和版本。

有人给我提供了一个类似于 github 的公共版本,所有这些都是自动模式。但年老并不快乐:这很复杂。

也许对你来说,这样的选择是合适的。

我宣布更改,甚至只为 MT4Orders 保留一顶帽子,因为我不是唯一使用它的人。

至于其他工作,我都是默默进行的。