程序库: MT4Orders - 页 24

 

对不起,我不会说俄语。

几天前,我发现了这个非常有趣的库。 但我有一个问题:我通过 OrderSend () 发送市场订单,并保存 OrderSend () 返回的票据。 一段时间后,止损被触及或获利。 然后,我尝试通过 OrderSelect(ticket,SELECT_BY_TICKET),用该票据选择订单。 在 MQL4 中,订单会在历史记录中找到。 但在 MQL5 中使用此库时,OrderSelect 将失败。

,我查看了一下 MT4orders.mqh 的代码。 MT4ORDERS::SelectByTicket()调用了SelectByExistingTicket(),后者失败,然后调用了SelectByHistoryTicket(),我预计后者会成功。 在 SelectByHistoryTicket() 中,HistoryDealSelect() 通常会返回 false(测试除外),因为票据是位置标识符,而不是交易票据。 HistoryOrderSelect()返回 true,因为票据与订单中的票据(和头寸标识符)相同(我在对冲模式下使用 MT5)。 但 MT4HISTORY::IsMT4Order(Ticket) 返回 false。 我希望它返回 true。 如果仓位 ID 为零,函数将返回 true。 但我发现在测试和实际票据中,项目 id 都不为零,而且等于订单中的订单位。

欢迎提供任何帮助。

 
winloosewin:

几天前,我发现了这个非常有趣的库。 但我有一个问题:我通过 OrderSend () 发送市场订单,并保存 OrderSend () 返回的票据。 一段时间后,止损被触及或获利。 然后,我尝试通过 OrderSelect(ticket,SELECT_BY_TICKET),用该票据选择订单。 在 MQL4 中,订单可以在历史记录中找到。 但在 MQL5 中使用此库时,OrderSelect 将失败。

这是正确的。详情在此 说明。

您可以使PositionTicket= OrderSend(OP_BUY, 2 lots) 和 OrderClose(0.2 lots) + OrderClose(0.3 lots)。这样就会得到两个平仓 "头寸"(0.2/0.3 手)和一个持仓 "头寸"(1.5 手),其交易票等于PositionTicket。这是 MT5 的一个特点。因此, SELECT_BY_TICKET+MODE_HISTORY 模式下,通过交易历史 中的POSITION_ID 选择仓位是不正确的。


记住票据是一种不好的方式,尽管它很流行。正确的方法是,在每次事件中,交易机器人都会从头开始读取整个环境。


ZY 在这里您可以看到与上述大致相同的情况

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

库:MT4Orders

fxsaber, 2018.04.14 09:10 AM

示例

#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

结果显示,以 ticket == 2 开立了一个仓位。然后关闭了两次,从而在交易历史中创建了两个关闭的 "头寸"。它们的票据不同,但两个 "仓位 "的 OrderTicketOpen 都 == 2。也就是说,您应该意识到,如果在 MT5 中平仓,其历史订单与实时订单并不一致。


请注意,在 MT5 中,即使是关闭同一实时仓位时的注释也是不同的:"Hello World!"和"tp 1.23614"。

 
winloosewin:

对不起,我不会说俄语。

几天前,我发现了这个非常有趣的库。 但我有一个问题:我通过 OrderSend () 发送市场订单,并保存 OrderSend () 返回的票据。 一段时间后,止损被触及或获利。 然后,我尝试通过 OrderSelect(ticket,SELECT_BY_TICKET),用该票据选择订单。 在 MQL4 中,订单可以在历史记录中找到。 但在 MQL5 中使用此库时,OrderSelect 将失败。

,我查看了一下 MT4orders.mqh 的代码。 MT4ORDERS::SelectByTicket()调用了SelectByExistingTicket(),后者失败了,然后调用了SelectByHistoryTicket(),我预计后者会成功。 在 SelectByHistoryTicket() 中,HistoryDealSelect() 通常会返回 false(测试除外),因为票据是位置标识符,而不是交易票据。 HistoryOrderSelect()返回 true,因为票据与订单中的票据(和头寸标识符)相同(我在对冲模式下使用 MT5)。 但 MT4HISTORY::IsMT4Order(Ticket) 返回 false。 我希望它返回 true。 如果仓位标识符为零,函数将返回 true。 但我看到在测试和实际票据中,项目 id 都不为零,而且等于订单中的订单位。

欢迎您提供帮助。

为了充分理解您的机器翻译,请附上英文文本

 

几天前,我发现了这个非常有趣的库。但我有一个问题:我通过 OrderSend() 发送市场订单,并存储 OrderSend() 返回的票据。一段时间后,止损或止盈 被触及。然后,我尝试通过
OrderSelect(ticket, SELECT_BY_TICKET),用该票据选择订单。在 MQL4 中,订单可以在历史记录中找到。但在 MQL5 中使用此库时,OrderSelect 并不成功。

我查看了一下 MT4orders.mqh 的代码。MT4ORDERS::SelectByTicket()调用了SelectByExistingTicket(),后者失败,然后调用了SelectByHistoryTicket(),我希望后者能成功。在 SelectByHistoryTicket() 中,函数 HistoryDealSelect() 通常返回 false(测试器中可能除外),因为票据是头寸标识符,而不是交易票据。 ::HistoryOrderSelect() 返回 true,因为票据与订单中的票据相同(也是头寸标识符)(我在对冲模式下使用 MT5)。但 MT4HISTORY::IsMT4Order(Ticket) 返回 false。我希望它返回 true。如果仓位标识符为零,函数就会返回 true。但我在测试器和真实账户中都看到,仓位标识符不为零,而是等于内单的订单票据。

换句话说:我不明白为什么在 MT4HISTORY::IsMT4Order() 函数中会出现以下代码(如果仓位标识符为零,则返回 true):

    return(/*(::HistoryOrderGetDouble(Ticket, ORDER_VOLUME_CURRENT) > 0) ||*/ !::HistoryOrderGetInteger(Ticket, ORDER_POSITION_ID));

下面附上我的测试代码:

void OnTick()
{
   PrintChangesOfMQL5OrderSystemState();

   int total=OrdersTotal();

   double bid = MarketInfo(Symbol(), MODE_BID);
   double ask = MarketInfo(Symbol(), MODE_ASK);

   static int state=0;
   static ulong ticket = 0;

   switch(state)
   {
      case 0:
         ticket = OrderSend(Symbol(), OP_BUY, 1.0, ask, 10, bid - 3*Point, bid + 3*Point);
         state=1;
         break;

      case 1:
         if(0==total)
         {
            bool res = OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES);
            if(false==res)
            {
               Print("OrderSelect failed with ticket: ", (string)ticket);
               Print("ORDER_POSITION_ID = ", (string)HistoryOrderGetInteger(ticket, ORDER_POSITION_ID));
               HistoryDealSelect(ticket);
               Print("HistoryDealSelect", (string)HistoryDealSelect(ticket), "   MT4HISTORY::IsMT4Deal", (string)MT4HISTORY::IsMT4Deal(ticket));
               HistoryOrderSelect(ticket);
               Print("HistoryOrderSelect", (string)HistoryOrderSelect(ticket), "   ORDER_POSITION_ID", ::HistoryOrderGetInteger(Ticket, ORDER_POSITION_ID));
               
               ExpertRemove();
            }
         }
         break;
   }
}

PrintChangesOfMQL5OrderSystemState() 是一个简单直接的函数,每次检测到变化时都会打印 MQL5 订单系统的状态。

以下是测试代码的输出(在测试仪上运行):

EURUSD  bid=1.087360   ask=1.087860
263207 EURUSD 2016.01.03 00:00:00  

HistDeal: ticket: 1  position_id: 0  MAGIC: 0  balance  open_price: 0.000000  volume: 0.000000  opened by order: 0  type=balance  reason=client  entry=in


--------------------
EURUSD  bid=1.087350   ask=1.087850
263207 EURUSD 2016.01.03 00:00:00  

HistDeal: ticket: 2  position_id: 2  MAGIC: 0  buy  open_price: 1.087860  volume: 1.000000  opened by order: 2  type=buy  reason=expert  entry=in
HistDeal: ticket: 1  position_id: 0  MAGIC: 0  balance  open_price: 0.000000  volume: 0.000000  opened by order: 0  type=balance  reason=client  entry=in

HistOrder ticket: 2  position_id: 2  MAGIC: 0  buy  open_price: 1.087860  volume: 1.000000  cur_vol=0.000000  type=buy  reason=expert
Order:    ticket: 0  position_id: 0  MAGIC: 0  buy  open_price: 0.000000  volume: 0.000000  cur_vol=0.000000  type=buy  reason=client

Position: ticket: 2  position_id: 2  MAGIC: 0  buy  open_price: 1.087860  volume: 1.000000  reason=expert

--------------------
EURUSD  bid=1.087330   ask=1.087830
263207 EURUSD 2016.01.03 00:00:16  

HistDeal: ticket: 3  position_id: 2  MAGIC: 0  sell  open_price: 1.087330  volume: 1.000000  opened by order: 3  type=sell  reason=stop loss  entry=out
HistDeal: ticket: 2  position_id: 2  MAGIC: 0  buy  open_price: 1.087860  volume: 1.000000  opened by order: 2  type=buy  reason=expert  entry=in
HistDeal: ticket: 1  position_id: 0  MAGIC: 0  balance  open_price: 0.000000  volume: 0.000000  opened by order: 0  type=balance  reason=client  entry=in

HistOrder ticket: 3  position_id: 2  MAGIC: 0  sell  open_price: 1.087330  volume: 1.000000  cur_vol=0.000000  type=sell  reason=stop loss
HistOrder ticket: 2  position_id: 2  MAGIC: 0  buy  open_price: 1.087860  volume: 1.000000  cur_vol=0.000000  type=buy  reason=expert

--------------------

OrderSelect failed with ticket:  2
ORDER_POSITION_ID =  2
HistoryDealSelect true    MT4HISTORY::IsMT4Deal false
HistoryOrderSelect true    MT4HISTORY::IsMT4Order false    ::HistoryOrderGetInteger(Ticket, ORDER_POSITION_ID) 2


可以看到,HistoryOrderGetInteger(Ticket, ORDER_POSITION_ID) 返回 2,而不是 0。这就是 MT4HISTORY::IsMT4Order() 返回 false 的原因。



如有任何帮助,不胜感激。
Общие принципы - Торговые операции - MetaTrader 5
Общие принципы - Торговые операции - MetaTrader 5
  • www.metatrader5.com
Перед тем как приступить к изучению торговых функций платформы, необходимо создать четкое представление об основных терминах: ордер, сделка и позиция. — это распоряжение брокерской компании купить или продать финансовый инструмент. Различают два основных типа ордеров: рыночный и отложенный. Помимо них существуют специальные ордера Тейк Профит...
 
winloosewin:
上面已经回答了 您的问题。


换句话说:我不明白为什么在函数 MT4HISTORY::IsMT4Order() 中会出现以下代码(如果仓位 id 为 0 则返回 true):

下面是我的测试代码:

PrintChangesOfMQL5OrderSystemState() 是一个简单直接的函数,每次检测到变化时都会打印 MQL5 订单系统的状态。

以下是测试代码的输出(在测试仪上运行):


您可以看到,HistoryOrderGetInteger(Ticket, ORDER_POSITION_ID)返回 2,而不是 0。这就是 MT4HISTORY::IsMT4Order() 返回 false 的原因。

您没有意识到 MT5 和 MT4 中的订单是不同的实体。

 
fxsaber:
上面已经回答了 您的问题。


您不明白 MT5 和 MT4 中的订单是不同的实体。

我了解 MQL5 和 MQL4 的订单系统及其区别。


fxsaber:
因此,在 SELECT_BY_TICKET+MODE_HISTORY 模式下,通过交易历史中的 POSITION_ID 选择仓位是不正确的。

是的,我知道 MQL5 函数HistoryOrderSelect() 希望使用票据而不是仓位标识符。

但我的测试代码是有效的 MQL4 代码(除了调用 MQL5 函数HistoryOrderSelect() 和HistoryDealSelect() 之外)。

而且在 MQL4 中,函数OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES) 如预期一样返回 true。

据我所知,该库的目的是在 MQL5 上尽可能好地模拟 MQL4 订单系统。因此,我希望

函数OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES) 也会返回 true。

我查看了代码,试图找出返回 false 的原因。

首先:由于我使用的是 MQL5 对冲系统,函数

ticket =OrderSend(Symbol(),OP_BUY,1.0, ask,10, bid -3*Point, bid +3*Point);

将等于 MQL5 对冲中(期货)头寸标识符的订单 ticket 赋值给变量 "ticket"。从代码中可以看到

    return((arrow_color == INT_MAX) ? (MT4ORDERS::NewOrderCheck() ? 0 : -1) :
           ((((int)arrow_color != INT_MIN) || MT4ORDERS::NewOrderCheck()) &&
            MT4ORDERS::OrderSend(MT4ORDERS::LastTradeRequest, MT4ORDERS::LastTradeResult) ?
            (MT4ORDERS::IsHedging ? (long)MT4ORDERS::LastTradeResult.order : // PositionID == Result.order是MT5-Hedge的一项功能
             ((MT4ORDERS::LastTradeRequest.action == TRADE_ACTION_DEAL) ?
              (MT4ORDERS::IsTester ? (::PositionSelect(MT4ORDERS::LastTradeRequest.symbol) ? PositionGetInteger(POSITION_TICKET) : 0) :
                                      // MT4ORDERS::OrderSend 中的 HistoryDealSelect
                                      ::HistoryDealGetInteger(MT4ORDERS::LastTradeResult.deal, DEAL_POSITION_ID)) :
              (long)MT4ORDERS::LastTradeResult.order)) : -1));

函数 MT4OrderSend() 的代码中可以看到。返回结果如下:

(long)MT4ORDERS::LastTradeResult.order : // PositionID == Result.order是MT5-Hedge的一项功能

在分析执行代码时库所做的工作时

bool res = OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES);

我看到函数 SelectByHistoryTicket() 使用我存储在变量 "ticket "中的票据执行。

在该函数中,函数 HistoryOrderSelect(ticket) 被调用,调用的票据等于订单票据和位置标识符。

在我的 MQL4OrderSelect() 调用 中,我自己并不调用 HistoryOrderSelect(ticket) - 它在库中。

只有在我的测试代码中,我才直接调用HistoryOrderSelect(ticket) 和 HistoryDealSelect(ticket),以查看在库中发生了什么:

/* 以下是 MQL5 而非 MQL4 代码 - 仅用于检查库内部发生的情况:*/
               Print("ORDER_POSITION_ID = ", (string)HistoryOrderGetInteger(ticket, ORDER_POSITION_ID));
               HistoryDealSelect(ticket);
               Print("HistoryDealSelect", (string)HistoryDealSelect(ticket), "   MT4HISTORY::IsMT4Deal", (string)MT4HISTORY::IsMT4Deal(ticket));
               HistoryOrderSelect(ticket);
               Print("HistoryOrderSelect", (string)HistoryOrderSelect(ticket), "   ORDER_POSITION_ID", ::HistoryOrderGetInteger(Ticket, ORDER_POSITION_ID));


简而言之:根据OrderSelect(ticket,SELECT_BY_TICKET,MODE _ TRADES)的返回值,库并没有在 MQL4 上模拟 MQL4订单 系统。

MQL4 订单系统。

 
winloosewin:

在 MQL4 中,函数OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES) 如预期返回 true。

据我所知,该库的目的是在 MQL5 上尽可能好地模拟 MQL4 订单系统。因此,我希望

函数OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES) 也会返回 true。

我查看了代码,试图找出返回 false 的原因。

您错了。在测试器中运行此智能交易系统

#include <MT4Orders.mqh>
#include <Debug.mqh> //https://c.mql5.com/3/173/Debug.mqh

#define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)

void OnTick()
{
  if (_P(OrderSelect(_P(OrderSend(_Symbol, OP_BUY, 1, Ask, 100, 0, 0)), SELECT_BY_TICKET)))
  {
    OrderPrint();
    _P(OrdersTotal());    
  }
  
  ExpertRemove();  
}


结果

2018.08.07 10:47:20.340 2018.08.01 00:00:00   instant buy 1.00 EURUSD at 1.16905 (1.16895 / 1.16905 / 1.16895)
2018.08.07 10:47:20.340 2018.08.01 00:00:00   deal #2  buy 1.00 EURUSD at 1.16905 done (based on order #2)
2018.08.07 10:47:20.340 2018.08.01 00:00:00   deal performed [#2  buy 1.00 EURUSD at 1.16905]
2018.08.07 10:47:20.340 2018.08.01 00:00:00   order performed buy 1.00 at 1.16905 [#2  buy 1.00 EURUSD at 1.16905]
2018.08.07 10:47:20.347 2018.08.01 00:00:00   void OnTick(), Line = 8: OrderSend(_Symbol,OP_BUY,1,Ask,100,0,0) = 2
2018.08.07 10:47:20.347 2018.08.01 00:00:00   void OnTick(), Line = 8: OrderSelect(_P(OrderSend(_Symbol,OP_BUY,1,Ask,100,0,0)),SELECT_BY_TICKET) = true
2018.08.07 10:47:20.347 2018.08.01 00:00:00   #2 2018.08.01 00:00:00 buy 1.00 EURUSD 1.16905 0.00000 0.00000 1.16895 0.00 0.00 -10.00 0
2018.08.07 10:47:20.347 2018.08.01 00:00:00   void OnTick(), Line = 11: OrdersTotal() = 1
2018.08.07 10:47:20.347 2018.08.01 00:00:00   ExpertRemove() function called
 

是的,我知道在开仓后直接 调用OrderSelect() 会返回 true

在这种情况下,我们有一个打开的 MQL5 仓位,库在调用OrderSelect() 时会找到该仓位

这是在库的内部函数 SelectByExistingTicket() 中完成的。


但关键是,当 MQL5 仓位被止损或止盈 平仓时,OrderSelect(ticket) 返回 false。

请执行我的测试代码进行验证(如果您的经纪商不接受如此接近的 SL 和 TP,请将它们放宽,以避免 OrderSend() 被拒绝)。

Общие принципы - Торговые операции - MetaTrader 5
Общие принципы - Торговые операции - MetaTrader 5
  • www.metatrader5.com
Перед тем как приступить к изучению торговых функций платформы, необходимо создать четкое представление об основных терминах: ордер, сделка и позиция. — это распоряжение брокерской компании купить или продать финансовый инструмент. Различают два основных типа ордеров: рыночный и отложенный. Помимо них существуют специальные ордера Тейк Профит...
 
winloosewin:

但关键是,当 MQL5 头寸被止损或止盈 平仓时,OrderSelect(ticket) 返回 false。

再次阅读我的部分详细解答

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

库:MT4Orders

fxsaber, 2018.08.06 14:21

没错。这里 有详细说明。

您可以执行PositionTicket= OrderSend(OP_BUY, 2 lots) 和 OrderClose(0.2 lots) + OrderClose(0.3 lots)。这样就会得到两个平仓 "头寸"(0.2/0.3 手)和一个未平仓头寸(1.5 手),其交易票等于PositionTicket这是 MT5 的一个特点。 因此, SELECT_BY_TICKET+MODE_HISTORY 模式下,通过交易历史 中的POSITION_ID 选择仓位是不正确的。


记住票据是一种不好的方式,尽管它很流行。正确的方法是,在每次事件中,交易机器人都会从头开始读取整个环境。


ZY 在这里,您可以看到与上述大致相同的情况


结果显示,开仓时 ticket == 2。然后它关闭了两次,从而在交易历史中创建了两个关闭的 "头寸"。它们的票据不同,但两个 "仓位 "的 OrderTicketOpen 都 == 2。也就是说,您应该意识到,如果在 MT5 中关闭头寸,其历史订单与实时订单并不一致。


请注意,在 MT5 中,即使是关闭同一实时仓位时的注释也是不同的:"Hello World!"和"tp 1.23614"。

在 MT5 中,无法通过 POSITION_ID 明确选择 MT4 平仓,因为可能同时存在多个 POSITION_ID 相同的 MT4 仓位。

 

谁使用 MT4Orders 中的mql4_to_mql5.mqh 文件进行 MT4 -> MT5 转换,请删除其中的这段代码。

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

测试 "CopyTicks

fxsaber, 2016.10.19 07:59

// 与 MT4 一样,允许处理时间序列:Open[Pos]、High[Pos]、Low[Pos]、Close[Pos]、Time[Pos]、Volume[Pos]。
// 它还设置了 MT4 的常用功能:iOpen、iHigh、iLow、iClose、iTime、iVolume。
#define DEFINE_TIMESERIE(NAME,FUNC,T)                                                                         \
  class CLASS##NAME                                                                                           \
  {                                                                                                           \
  public:                                                                                                     \
    static T Get( const string Symb, const int TimeFrame, const int iShift )                                  \
    {                                                                                                         \
      T tValue[];                                                                                             \
                                                                                                              \
      return((Copy##FUNC((Symb == NULL) ? _Symbol : Symb, _Period, iShift, 1, tValue) > 0) ? tValue[0] : -1); \
    }                                                                                                         \
                                                                                                              \
    T operator []( const int iPos ) const                                                                     \
    {                                                                                                         \
      return(CLASS##NAME::Get(_Symbol, _Period, iPos));                                                       \
    }                                                                                                         \
  };                                                                                                          \
                                                                                                              \
  CLASS##NAME NAME;                                                                                           \
                                                                                                              \
  T i##NAME( const string Symb, const int TimeFrame, const int iShift )                                       \
  {                                                                                                           \
    return(CLASS##NAME::Get(Symb, TimeFrame, iShift));                                                        \
  }

DEFINE_TIMESERIE(Volume, TickVolume, long)
DEFINE_TIMESERIE(Time, Time, datetime)
DEFINE_TIMESERIE(Open, Open, double)
DEFINE_TIMESERIE(High, High, double)
DEFINE_TIMESERIE(Low, Low, double)
DEFINE_TIMESERIE(Close, Close, double)

正式与 MT5 内置 1860 这段代码无关

Новая версия платформы MetaTrader 5 build 1860: Функции для работы с барами в MQL5 и улучшения в тестере стратегий
Новая версия платформы MetaTrader 5 build 1860: Функции для работы с барами в MQL5 и улучшения в тестере стратегий
  • 2018.06.14
  • www.mql5.com
Новая версия платформы MetaTrader 5 build 1860: Функции для работы с барами в MQL5 и улучшения в тестере стратегий15 июня 2018 года будет опубликов...