程序库: MT4Orders - 页 20

 

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

mql5 语言的特点、精妙之处和工作技巧

fxsaber, 2018.02.19 08:39 AM

在同一时间,同一符号上的净价可以是一个未平仓头寸和多个任意方向的市场订单。例如,一个买入头寸和一个买入订单。

在 MT5 库中,MT5 订单和 MT5 仓位是一个实体 - MT4 订单。因此,在这种情况下,有可能在净额结算账户的一个符号上获得多个买入/卖出-MT4 订单。这不是错误,也不会导致任何不良后果。但我还是要写出来,以防有人对这种情况感到惊讶。

的确,我还没有找到这样的模拟账户。

这只是理论上的警告。我在实践中没有遇到过这种情况。

 
图书馆故意不在竞价历史记录 中显示这些订单(非常罕见)。早期版本的 bibla 会看到它们。如果您认为当前的行为也应如此,请告诉我。
 
// 更改列表:
// 06.03.2018
// 添加:添加 TICKET_TYPE 和 MAGIC_TYPE,以便编写统一的跨平台代码
// 无编译器警告(包括 MQL4 严格模式)。

以下是在 MQL4/5 下编译无警告的代码

#property strict

#include <MT4Orders.mqh>

void OnStart()
{
// long Ticket = 0;
// long Magic = 0;
  TICKET_TYPE Ticket = 0;
  MAGIC_TYPE  Magic = 0;
  
  long Tmp = OrderSelect(Ticket, SELECT_BY_TICKET) + 
             OrderDelete(Ticket) +
             OrderCloseBy(Ticket, Ticket) +
             OrderClose(Ticket, 1, 0, 0) +    
             OrderSend(_Symbol, OP_BUY, 1, 0, 0, 0, 0, NULL, Magic);
}

感谢@Andrey Voytenko 提出此解决方案!

 
fxsaber:

以下是在 MQL4/5 下编译无警告的代码

感谢@Andrey Voytenko 提出此解决方案!

这个 hack 有什么用?

 
Rashid Umarov:

这个 hack 有什么用?

长类型在示例中被注释掉了。如果保留它们,在 MQL5 和 NoStrict-MQL4 中将不会出现警告。但在严格-MQL4 中,它们会出现。

为了编写跨平台库时不出现相应的警告,我们添加了这一功能。

你根本不需要使用它。这对于那些可能面临此类跨平台任务的人来说是一个额外的便利。

 

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

从 MT4 到 MT5 的机器人

fxsaber, 2018.03.08 09:27 pm.

//https://www.mql5.com/zh/code/16006
#define   MT4_TICKET_TYPE // 命令发送(OrderSend)和订单票据(OrderTicket)必须返回与 MT4 相同类型的值 - int。
#include <MT4Orders.mqh>
#include <MQL4_To_MQL5.mqh>

int Hour( void )
{
  return((int)((TimeCurrent() % (24 * 3600)) / 3600));
}

int Minute( void )
{
  return((int)((TimeCurrent() % 3600) / 60));
}

#include "super-signals-channel.mq4" //https://www.mql5.com/ru/forum/231135#comment_6751304
 

我正在尝试实施一个策略(显然在 MT4 中运行良好),但却遇到了障碍。

每当产生一个新信号时,EA 就会开始一个新的交易序列,因此每个交易对通常会有多个序列在运行。

每笔交易都有 SL 和 TP,EA 需要通过检查订单历史记录来跟踪每个序列中最近一笔交易的情况(SL 或 TP)。

遗憾的是,根据库注释(如下)和为使系统正常工作所做的各种尝试,这似乎是不可能的:

// 在 MT4 中,SELECT_BY_TICKET 模式下的 OrderSelect 选择票据,无论 MODE_TRADES / MODE_HISTORY,
// 因为 "票据号码是唯一的订单 ID"。
// 在 MT5 中,票据编号不是唯一的,
// 因此,在 SELECT_BY_TICKET 模式下,OrderSelect 对匹配票据的选择优先级如下:
// MODE_TRADES:现有仓位>现有订单>交易>取消订单
// MODE_HISTORY:交易>取消订单>现有仓位>现有订单

通过实验,我确认在发生 SL/TP 事件后,票据编号总是会改变,唯一的共同信息就是神奇编号,甚至连订单注释都不会保留。

在测试中,下达带有 SL、TP、神奇数字和交易注释的初始订单会返回 2 号订单,并显示所有预期信息。

但是,当触及 SL 或 TP 时,交易单 #2 就会消失,无法使用 SELECT_BY_POS 或 SELECT_BY_TICKET 进行检索。

取而代之的是(假设没有其他交易活动)没有设置订单注释的 3 号交易单。

由于票据编号不一致,也没有订单注释可供参考,因此似乎没有简单的方法来确定给定序列中的最后一个订单:(

希望@fxsaber 能找到解决方案或提出变通办法:)

 
SysFX:

遗憾的是,我并不了解这个问题。

 

很抱歉这么晚才回复 :(

问题在于,"MODE_HISTORY "交易信息基本上无法使用,因为

1)当交易关闭时,交易单号会发生变化......您可以很容易地测试这一点,方法是打开一个带 TP 和 SL 的买入/卖出交易--如果交易打开时是交易单号 #2,那么在触发 SL 或 TP 后,该交易将成为历史库中的交易单号 #3。

2) 神奇数字丢失

3) 票据注释丢失

因此,如果 EA 代码需要检查 交易是否以盈利或亏损收盘,这是不可能的,因为没有可用的信息来识别交易。

我希望您能调整一下,保留神奇数字,并使交易注释的行为与 MT4 相似--也许您还能找到保留票据编号的方法。

 
SysFX:

对不起,我的回复晚了 :(

问题是 "MODE_HISTORY "交易信息基本上无法使用,因为

1)当交易关闭时,票据编号会发生变化......您可以通过打开一个带 TP 和 SL 的买入/卖出交易来轻松测试这一点 - 如果交易以票据 #2 打开,则在触发 SL 或 TP 后,该交易将成为历史库中的票据 #3

2) 神奇数字丢失

3) 票据注释丢失

因此,如果 EA 代码需要检查某笔交易是以盈利还是亏损收盘,这是不可能的,因为没有可用的信息来识别该笔交易。

我希望您能调整一下,保留神奇数字,并使交易注释的行为与 MT4 相似--也许您还能找到保留票据编号的方法。

示例

#include <MT4Orders.mqh>

#define Bid SymbolInfoDouble(_Symbol, SYMBOL_BID)
#define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)

#define  PRINT(A) Print(#A + " = " + (string)(A))

void OnInit()
{
  long Ticket;
  
  PRINT((Ticket = OrderSend(_Symbol, OP_BUY, 1, Ask, 0, Bid - 100 * _Point, Bid + 100 * _Point, "Hello World!", 12345)));
  
  if (OrderSelect(Ticket, SELECT_BY_TICKET))
    PRINT(OrderClose(OrderTicket(), 0.3, OrderClosePrice(), 0));
}

void OnDeinit( const int )
{
  const int Total = OrdersHistoryTotal();
  
  for (int i = 1; i < Total; i++)
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
    {
      OrderPrint();
      
      PRINT(OrderTicket());
      PRINT(OrderMagicNumber());
      PRINT(OrderComment());
      PRINT(OrderTicketOpen());
    }
}


交易结果

2018.03.25 00:00:00   instant buy 1.00 EURUSD at 1.23527 sl: 1.23414 tp: 1.23614 (1.23514 / 1.23527)
2018.03.25 00:00:00   deal #2  buy 1.00 EURUSD at 1.23527 done (based on order #2)
2018.03.25 00:00:00   deal performed [#2  buy 1.00 EURUSD at 1.23527]
2018.03.25 00:00:00   order performed buy 1.00 at 1.23527 [#2  buy 1.00 EURUSD at 1.23527]
2018.03.25 00:00:00   (Ticket=OrderSend(_Symbol,OP_BUY,1,Ask,0,Bid-100*_Point,Bid+100*_Point,Hello World!,12345)) = 2
2018.03.25 00:00:00   instant sell 0.30 EURUSD at 1.23514, close #2 (1.23514 / 1.23527)
2018.03.25 00:00:00   deal #3  sell 0.30 EURUSD at 1.23514 done (based on order #3)
2018.03.25 00:00:00   deal performed [#3  sell 0.30 EURUSD at 1.23514]
2018.03.25 00:00:00   order performed sell 0.30 at 1.23514 [#3  sell 0.30 EURUSD at 1.23514]
2018.03.25 00:00:00   OrderClose(OrderTicket(),0.3,OrderClosePrice(),0) = true
2018.03.26 01:04:40   take profit triggered #2  buy 0.70 EURUSD 1.23527 sl: 1.23414 tp: 1.23614 [#4  sell 0.70 EURUSD at 1.23614]
2018.03.26 01:04:40   deal #4  sell 0.70 EURUSD at 1.23614 done (based on order #4)
2018.03.26 01:04:40   deal performed [#4  sell 0.70 EURUSD at 1.23614]
2018.03.26 01:04:40   order performed sell 0.70 at 1.23614 [#4  sell 0.70 EURUSD at 1.23614]
final balance 10000046.11 EUR
2018.03.26 23:59:59   #3 2018.03.25 00:00:00 buy 0.30 EURUSD 1.23527 1.23414 1.23614 2018.03.25 00:00:00 1.23514 0.00 0.00 -3.16 Hello World! 12345
2018.03.26 23:59:59   OrderTicket() = 3
2018.03.26 23:59:59   OrderMagicNumber() = 12345
2018.03.26 23:59:59   OrderComment() = Hello World!
2018.03.26 23:59:59   OrderTicketOpen() = 2
2018.03.26 23:59:59   #4 2018.03.25 00:00:00 buy 0.70 EURUSD 1.23527 0.00000 1.23614 2018.03.26 01:04:40 1.23614 0.00 0.00 49.27 tp 1.23614 12345
2018.03.26 23:59:59   OrderTicket() = 4
2018.03.26 23:59:59   OrderMagicNumber() = 12345
2018.03.26 23:59:59   OrderComment() = tp 1.23614
2018.03.26 23:59:59   OrderTicketOpen() = 2

止损 平仓,一些经纪商会用 [tp] 或 [sl] 替换注释!


PS俄罗斯讨论主题