程序库: MT4Orders - 页 11

 
Aliaksandr Kryvanos:
我明白了,你能否告诉我如何让 GetLastError() 也输出交易服务器错误,如果你还没有时间,我可以自己写。谢谢
与 OrdersTotal 的实现思路相同。我可能会写一个扩展的GetLastError。还有 GetLastTradeRequest() 和 GetLastTradeResult()。
 
fxsaber:
我很可能会编写一个扩展的 GetLastError。还有 GetLastTradeRequest() 和 GetLastTradeResult()。

在对 GetLastError 进行研究后,我认为对其进行补充并不合适。

检查之后,将提供更新

// 更改列表:
// 08.02.2017:
// 添加:MT4ORDERS::LastTradeRequest 和 MT4ORDERS::LastTradeResult 变量包含相应的 MT5-OrderSend 数据。

现在可以完整接收所有 MT5 订单发送数据。

 
// 该脚本可让您快速了解如何在 MT5-OrderSend 中形成与 MT5 兼容的 MT4 类似的 MqlTradeRequest-request。

#define TOSTRING(A)  #A + " = " + (string)(A) + "\n"
#define TOSTRING2(A) #A + " = " + EnumToString(A) + " (" + (string)(A) + ")\n"

string ToString( const MqlTradeRequest &Request )
{
  return(TOSTRING2(Request.action) + TOSTRING(Request.magic) + TOSTRING(Request.order) +
         TOSTRING(Request.symbol) + TOSTRING(Request.volume) + TOSTRING(Request.price) +
         TOSTRING(Request.stoplimit) + TOSTRING(Request.sl) +  TOSTRING(Request.tp) +
         TOSTRING(Request.deviation) + TOSTRING2(Request.type) + TOSTRING2(Request.type_filling) +
         TOSTRING2(Request.type_time) + TOSTRING(Request.expiration) + TOSTRING(Request.comment) +
         TOSTRING(Request.position) + TOSTRING(Request.position_by));
}

string ToString( const MqlTradeResult &Result )
{
  return(TOSTRING(Result.retcode) + TOSTRING(Result.deal) + TOSTRING(Result.order) +
         TOSTRING(Result.volume) + TOSTRING(Result.price) + TOSTRING(Result.bid) +
         TOSTRING(Result.ask) + TOSTRING(Result.comment) + TOSTRING(Result.request_id) +
         TOSTRING(Result.retcode_external));
}

#include <MT4Orders.mqh>

#define PRINT(A) A; Print(#A + "\n" + ToString(MT4ORDERS::LastTradeRequest) + ToString(MT4ORDERS::LastTradeResult));

#define Point _Point
#define Bid (::SymbolInfoDouble(_Symbol, ::SYMBOL_BID))
#define Ask (::SymbolInfoDouble(_Symbol, ::SYMBOL_ASK))

void OnStart()
{
  Print(TOSTRING(AccountInfoString(ACCOUNT_SERVER)));
  
  // 打开位置
  const int TicketPosition = PRINT(OrderSend(NULL, OP_BUY, 1, Ask, 100, 0, 0, "My Position"))

  if (OrderSelect(TicketPosition, SELECT_BY_TICKET))
  {
    // 设置 SL/TP
    PRINT(OrderModify(OrderTicket(), OrderOpenPrice(), Bid - 100 * Point, Bid + 100 * Point, 0))

    // 关闭位置
    PRINT(OrderClose(OrderTicket(), OrderLots(), Bid, 100))
  }

  // 设置挂单
  const int TicketOrder = PRINT(OrderSend(NULL, OP_BUYLIMIT, 1, Ask - 100 * Point, 100, 0, 0, "My Order"))

  if (OrderSelect(TicketOrder, SELECT_BY_TICKET))
  {
    // 授权令已被删除
    PRINT(OrderDelete(OrderTicket()))
  }
}
[删除]  
非常好用,谢谢
 
脚本工作的结果
AccountInfoString(ACCOUNT_SERVER) = FXOpen-MT5

OrderSend(NULL,OP_BUY,1,Ask,100,0,0,My Position)
Request.action = TRADE_ACTION_DEAL (1)
Request.magic = 0
Request.order = 0
Request.symbol = EURUSD
Request.volume = 1.0
Request.price = 1.06455
Request.stoplimit = 0.0
Request.sl = 0.0
Request.tp = 0.0
Request.deviation = 100
Request.type = ORDER_TYPE_BUY (0)
Request.type_filling = ORDER_FILLING_IOC (1)
Request.type_time = ORDER_TIME_GTC (0)
Request.expiration = 1970.01.01 00:00:00
Request.comment = My Position
Request.position = 0
Request.position_by = 0
Result.retcode = 10009
Result.deal = 9320
Result.order = 57775
Result.volume = 1.0
Result.price = 0.0
Result.bid = 0.0
Result.ask = 0.0
Result.comment = My Position
Result.request_id = 589
Result.retcode_external = 0

OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice()-100*Point,OrderOpenPrice()+100*Point,0)
Request.action = TRADE_ACTION_SLTP (6)
Request.magic = 0
Request.order = 0
Request.symbol = EURUSD
Request.volume = 0.0
Request.price = 0.0
Request.stoplimit = 0.0
Request.sl = 1.06355
Request.tp = 1.06555
Request.deviation = 0
Request.type = ORDER_TYPE_BUY (0)
Request.type_filling = ORDER_FILLING_FOK (0)
Request.type_time = ORDER_TIME_GTC (0)
Request.expiration = 1970.01.01 00:00:00
Request.comment =
Request.position = 57775
Request.position_by = 0
Result.retcode = 10009
Result.deal = 0
Result.order = 0
Result.volume = 1.0
Result.price = 0.0
Result.bid = 0.0
Result.ask = 0.0
Result.comment = Request executed
Result.request_id = 590
Result.retcode_external = 0

OrderClose(OrderTicket(),OrderLots(),Bid,100)
Request.action = TRADE_ACTION_DEAL (1)
Request.magic = 0
Request.order = 0
Request.symbol = EURUSD
Request.volume = 1.0
Request.price = 1.0645
Request.stoplimit = 0.0
Request.sl = 0.0
Request.tp = 0.0
Request.deviation = 100
Request.type = ORDER_TYPE_SELL (1)
Request.type_filling = ORDER_FILLING_IOC (1)
Request.type_time = ORDER_TIME_GTC (0)
Request.expiration = 1970.01.01 00:00:00
Request.comment =
Request.position = 57775
Request.position_by = 0
Result.retcode = 10009
Result.deal = 9321
Result.order = 57776
Result.volume = 1.0
Result.price = 0.0
Result.bid = 0.0
Result.ask = 0.0
Result.comment = Request executed
Result.request_id = 591
Result.retcode_external = 0

OrderSend(NULL,OP_BUYLIMIT,1,Ask-100*Point,100,0,0,My Order)
Request.action = TRADE_ACTION_PENDING (5)
Request.magic = 0
Request.order = 0
Request.symbol = EURUSD
Request.volume = 1.0
Request.price = 1.06356
Request.stoplimit = 0.0
Request.sl = 0.0
Request.tp = 0.0
Request.deviation = 100
Request.type = ORDER_TYPE_BUY_LIMIT (2)
Request.type_filling = ORDER_FILLING_IOC (1)
Request.type_time = ORDER_TIME_GTC (0)
Request.expiration = 1970.01.01 00:00:00
Request.comment = My Order
Request.position = 0
Request.position_by = 0
Result.retcode = 10009
Result.deal = 0
Result.order = 57777
Result.volume = 1.0
Result.price = 1.06356
Result.bid = 0.0
Result.ask = 0.0
Result.comment = My Order
Result.request_id = 592
Result.retcode_external = 0

OrderDelete(OrderTicket())
Request.action = TRADE_ACTION_REMOVE (8)
Request.magic = 0
Request.order = 57777
Request.symbol =
Request.volume = 0.0
Request.price = 0.0
Request.stoplimit = 0.0
Request.sl = 0.0
Request.tp = 0.0
Request.deviation = 0
Request.type = ORDER_TYPE_BUY (0)
Request.type_filling = ORDER_FILLING_FOK (0)
Request.type_time = ORDER_TIME_GTC (0)
Request.expiration = 1970.01.01 00:00:00
Request.comment =
Request.position = 0
Request.position_by = 0
Result.retcode = 10009
Result.deal = 0
Result.order = 57777
Result.volume = 1.0
Result.price = 1.06356
Result.bid = 0.0
Result.ask = 0.0
Result.comment = My Order
Result.request_id = 593
Result.retcode_external = 0
现在很容易理解如何在 MT5 中正确生成适当的交易请求 了。
 
// 该脚本检查 MT5 交易订单主要类型的处理速度特性。

#define TOSTRING(A)  #A + " = " + (string)(A) + "\n"
#define TOSTRING2(A) #A + " = " + EnumToString(A) + " (" + (string)(A) + ")\n"

string ToString( const MqlTradeRequest &Request )
{
  return(TOSTRING2(Request.action) + TOSTRING(Request.magic) + TOSTRING(Request.order) +
         TOSTRING(Request.symbol) + TOSTRING(Request.volume) + TOSTRING(Request.price) +
         TOSTRING(Request.stoplimit) + TOSTRING(Request.sl) +  TOSTRING(Request.tp) +
         TOSTRING(Request.deviation) + TOSTRING2(Request.type) + TOSTRING2(Request.type_filling) +
         TOSTRING2(Request.type_time) + TOSTRING(Request.expiration) + TOSTRING(Request.comment) +
         TOSTRING(Request.position) + TOSTRING(Request.position_by));
}

string ToString( const MqlTradeResult &Result )
{
  return(TOSTRING(Result.retcode) + TOSTRING(Result.deal) + TOSTRING(Result.order) +
         TOSTRING(Result.volume) + TOSTRING(Result.price) + TOSTRING(Result.bid) +
         TOSTRING(Result.ask) + TOSTRING(Result.comment) + TOSTRING(Result.request_id) +
         TOSTRING(Result.retcode_external));
}

ENUM_DAY_OF_WEEK GetDayOfWeek( const datetime time )
{
  MqlDateTime sTime = {0};

  ::TimeToStruct(time, sTime);

  return((ENUM_DAY_OF_WEEK)sTime.day_of_week);
}

bool SessionTrade( const string Symb )
{
  datetime TimeNow = ::TimeTradeServer();

  const ENUM_DAY_OF_WEEK DayOfWeek = GetDayOfWeek(TimeNow);

  TimeNow %= 24 * 60 * 60;

  bool Res = false;
  datetime From, To;

  for (int i = 0; (!Res) && ::SymbolInfoSessionTrade(Symb, DayOfWeek, i, From, To); i++)
    Res = ((From <= TimeNow) && (TimeNow < To));

  return(Res);
}

bool SymbolTrade( const string Symb )
{
  MqlTick Tick;

  return(::SymbolInfoTick(Symb, Tick) ? ((Tick.bid != 0) && (Tick.ask != 0) && SessionTrade(Symb) &&
         ((ENUM_SYMBOL_TRADE_MODE)::SymbolInfoInteger(Symb, SYMBOL_TRADE_MODE) == SYMBOL_TRADE_MODE_FULL)) : false);
}

#define MT4ORDERS_BENCHMARK Alert(MT4ORDERS::LastTradeRequest.symbol + " " +       \
                                  (string)MT4ORDERS::LastTradeResult.order + " " + \
                                  MT4ORDERS::LastTradeResult.comment);             \
                            Print(ToString(MT4ORDERS::LastTradeRequest) +          \
                                  ToString(MT4ORDERS::LastTradeResult));

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


#define Point (SymbolInfoDouble(Symb, SYMBOL_POINT))
#define Bid (SymbolInfoDouble(Symb, SYMBOL_BID))
#define Ask (SymbolInfoDouble(Symb, SYMBOL_ASK))

void Benchmark( string Symb = NULL, uint LimitOffset = 1000 )
{
  if (Symb == NULL)
    Symb = _Symbol;

  if (SymbolTrade(Symb))
  {
    const bool DemoAccount = ((ENUM_ACCOUNT_TRADE_MODE)AccountInfoInteger(ACCOUNT_TRADE_MODE) == ACCOUNT_TRADE_MODE_DEMO);
    const double MinLot = SymbolInfoDouble(Symb, SYMBOL_VOLUME_MIN);

    const uint StopLevel = (uint)SymbolInfoInteger(Symb, SYMBOL_TRADE_STOPS_LEVEL);

    if (StopLevel != 0)
      LimitOffset = StopLevel;

    if (DemoAccount && OrderSelect(OrderSend(Symb, OP_BUY, MinLot, Ask, 100, 0, 0, __FUNCTION__ + "_Position"), SELECT_BY_TICKET))
    {
      OrderModify(OrderTicket(), OrderOpenPrice(), 0, Bid + LimitOffset * Point, 0);
      OrderClose(OrderTicket(), OrderLots(), Bid, 100);
    }

    double PriceMin = SymbolInfoDouble(Symb, SYMBOL_SESSION_PRICE_LIMIT_MIN);

    if (PriceMin < Point)
      PriceMin = MathMax(Ask - LimitOffset * Point, Point);

    if ((PriceMin < Ask) &&
        OrderSelect(OrderSend(Symb, OP_BUYLIMIT, MinLot, PriceMin, 100, 0, 0, __FUNCTION__ + "_Order"), SELECT_BY_TICKET) &&
        (!OrderDelete(OrderTicket())) && (!DemoAccount))
    {
      Alert("OrderDelete ERROR, Check Now!");

      ExpertRemove();
    }
  }
}
void OnStart()
{
  if ((ENUM_ACCOUNT_TRADE_MODE)AccountInfoInteger(ACCOUNT_TRADE_MODE) == ACCOUNT_TRADE_MODE_DEMO) // 如果您想查看实物,请注释出来
  {
    Alert(TOSTRING(AccountInfoString(ACCOUNT_SERVER)));
    Alert(TOSTRING(TerminalInfoInteger(TERMINAL_PING_LAST)));

    while (!IsStopped())
      for (int i = SymbolsTotal(true) - 1; (i >= 0) && (!IsStopped()); i--)
        Benchmark(SymbolName(i, true));
  }
}

在该脚本的帮助下,我找到了 MT5 的执行问题。我建议您检查您的终端和交易服务器,如有问题,请向服务台报告。

[删除]  
fxsaber:

在该脚本的帮助下,我发现了 MT5 的执行问题。我建议您检查您的终端+交易服务器,如有问题,请向服务台报告。

例如,1533 版本已经在 result.comment 中提供了延迟信息?
 
Alexey Kozitsyn:
所以,1533 版已经在 result.comment 中提供了延迟信息?

不是,这是由程序库完成的。

第二个数字是在执行 OrderSend 之后同步订单(交易)历史所需的时间(在收到OnTradeTransaction 中相应事件之后的时间)。

在截图中,这个数字达到了 28 毫秒,这是非常高的。SD 也在处理这个问题。

如果 MT5 毫发无损地通过压力测试,那将是非常好的结果。每个人都可以测试自己的 MT5。

 

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

脚本: 关闭所有头寸

fxsaber, 2017.03.30 14:11

// MQL4&5 代码

#property script_show_inputs

#include <MT4Orders.mqh>

sinput int RTOTAL = 4;            // 不成功交易的重复次数
sinput int SLEEPTIME = 1;         // 重复之间的暂停时间,以秒为单位
sinput int Deviation_ = 10;       // 价格偏差
sinput bool exAllSymbols = false; // false - 仅当前字符,true - 所有字符

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

bool CloseAllPositions( const bool AllSymbols = true, const int Slippage = 0 )
{
  bool Res = true;
  
  MqlTick Tick;
  
  for (int i = OrdersTotal() - 1; _CS(i >= 0); i--)
    if (OrderSelect(i, SELECT_BY_POS) && (OrderType() <= OP_SELL) &&
        (AllSymbols ? true : (OrderSymbol() == Symbol())) && SymbolInfoTick(OrderSymbol(), Tick))
      Res &= OrderClose(OrderTicket(), OrderLots(), (OrderType() == OP_BUY) ? Tick.bid : Tick.ask, Slippage);
      
  return(Res);
}

void OnStart()
{
  for (int i = 0; _CS((i < RTOTAL) && (!CloseAllPositions(exAllSymbols, Deviation_))); i++)
    Sleep(SLEEPTIME * 1000);
}