程序库: MT4 订单快速报告 - 页 4

 
Forester #:

结果发现,MQ 测试仪将删除的限价订单转移到存档时出现了延迟:

请提供数据以供复制。
 
Forester #:

我改用了 highchart。结果发现效果更好:google.charts 在显示 700,000 笔交易时会冻结,而 highchart 在显示这些交易时没有特别的刹车,而且可以放大到单笔交易。

在目前的实现中,highchart 要求在线,这是否正确?
 
fxsaber #:
请提供数据以供复制。
 // 与 #define VIRTUAL_TESTER 的区别 - 通过 SelectByIndex() 而不是 #define VIRTUAL_TESTER 连接虚拟测试器
 
 #include <MT4Orders.mqh>

#define  REPORT_TESTER             // 测试仪将自动记录报告
//#define  REPORT_BROWSER            // 在浏览器启动时创建报告 - 需要 DLL 许可。
#include <MT4Orders_QuickReport.mqh>//

input int inAmount = 10;
input int inOffset = 5;
input int inRange = 0;

bool OrdersBuy[];
bool OrdersSell[];
bool OrdersBuyStop[];
bool OrdersSellStop[];

void OnInit()
{
  ArrayResize(OrdersBuy, inAmount + 1);
  ArrayResize(OrdersSell, inAmount + 1);
  ArrayResize(OrdersBuyStop, inAmount + 1);
  ArrayResize(OrdersSellStop, inAmount + 1);
}

void OnTick()
{

   strategy ();

}

double OnTester() { 
QuickReport("report_0", true, 0);
   return(AccountInfoDouble(ACCOUNT_BALANCE)); 
}

void OnDeinit(const int  reason ){
   Print("OnDeinit main");

}


int TimeHour     ( datetime time ){return((int)((time / 3600) % 24));}//current hour in day.每小时 3600 秒

void strategy (){
  string Symb = _Symbol;
  MqlTick Tick;
  
  if (SymbolInfoTick(Symb, Tick))
  {    
    double sl, tp, point = SymbolInfoDouble(Symb, SYMBOL_POINT);
    const double Offset = inOffset * point;

    ArrayInitialize(OrdersBuy, false);
    ArrayInitialize(OrdersSell, false);
    ArrayInitialize(OrdersBuyStop, false);
    ArrayInitialize(OrdersSellStop, false);

    for (uint i = OrdersTotal(); (bool)i--;)
      if (OrderSelect(i, SELECT_BY_POS))         
      {
        ulong Magic = OrderMagicNumber();
        if(Magic > 0 && Magic < 100 ){
           switch (OrderType())
           {
             case OP_BUY:
               OrderModify(OrderTicket(), OrderOpenPrice(), 0, Tick.bid + Magic * Offset, 0);
               OrdersBuy[Magic] = true;
               
               break;
             case OP_SELL:
               OrderModify(OrderTicket(), OrderOpenPrice(), 0, Tick.ask - Magic * Offset, 0);
               OrdersSell[Magic] = true;
               
               break;
             case OP_BUYLIMIT:
               OrderModify(OrderTicket(), Tick.ask - Magic * Offset, 0, 0, 0);
               OrdersBuy[Magic] = true;
               
               break;
             case OP_SELLLIMIT:          
               OrderModify(OrderTicket(), Tick.bid + Magic * Offset, 0, 0, 0);
               OrdersSell[Magic] = true;
               
               break;
           }
         }
         
        if(Magic > 100 && Magic < 200 ){
           Magic = Magic - 100;
           switch (OrderType())
           { 
             case OP_BUY:
               OrderModify(OrderTicket(), OrderOpenPrice(), 0, Tick.bid + Magic * Offset, 0);
               OrdersBuyStop[Magic] = true;
               
               break;
             case OP_SELL:
               OrderModify(OrderTicket(), OrderOpenPrice(), 0, Tick.ask - Magic * Offset, 0);
               OrdersSellStop[Magic] = true;
               
               break;
             case OP_BUYSTOP:
               OrderModify(OrderTicket(), Tick.ask + Magic * Offset, 0, 0, 0);
               OrdersBuyStop[Magic] = true;
               
               break;
             case OP_SELLSTOP:          
               OrderModify(OrderTicket(), Tick.bid - Magic * Offset, 0, 0, 0);
               OrdersSellStop[Magic] = true;
               
               break;
           }
           
         }
         if(Magic == 1001 ){//检查是否完全关闭
           OrderClose(OrderTicket(), OrderLots(), (OrderType()==OP_BUY ? Tick.bid : Tick.ask), 0 ) ;//检查全封闭 - 正常
         }
         
         //检查不同刻度线的部分闭合情况
         if(Magic == 1002 ){
           double Lots = OrderLots();
           if(Lots==10){//主要地段 - 关闭 25
               double LotsDel1=NormalizeDouble(Lots/4, 2);// 关闭原有地段的 25
               OrderClose(OrderTicket(), LotsDel1, (OrderType()==OP_BUY ? Tick.bid : Tick.ask), 0 ) ;//检查部分关闭
           }else{ // 在下一个 tick 时关闭余额
              OrderClose(OrderTicket(), Lots, (OrderType()==OP_BUY ? Tick.bid : Tick.ask), 0 ) ;//检查是否完全关闭
           }
         }
            
         //检查在同一刻度上部分关闭 OrderClose()。这在虚拟测试器中不起作用--它会以 1/2 手的价格执行许多订单。 
         //因为在第一次订单发送后将创建新的票据,而在第二次订单发送时将找不到旧的票据,因此将创建第三张票据。
         if(Magic == 1003 ){
           double Lots = OrderLots();
           double LotsDel1=NormalizeDouble(Lots/3, 2);// 关闭原有地段的 33
           OrderClose(OrderTicket(), LotsDel1,                         (OrderType()==OP_BUY ? Tick.bid : Tick.ask), 0 ) ;//检查部分关闭
           OrderClose(OrderTicket(), NormalizeDouble(Lots-LotsDel1,2), (OrderType()==OP_BUY ? Tick.bid : Tick.ask), 0 ) ;//在同一个勾上检查余额是否全部关闭--此处出现故障
         }
         
         if(Magic == 1004 ){
           //OrderCloseBy(); //检查出来
         }
         if(Magic == 1005 ){
            OrderDelete(OrderTicket());
         }

      }
     
    if(TimeHour(TimeCurrent())<23 && TimeHour(TimeCurrent())>0 ){return;} // 执行从 0 到 1 和从 23 到 0 的运算
 
    for (int i = 1; i <= inAmount; i++)
    {
      if (!OrdersBuy[i])
        OrderSend(Symb, OP_BUYLIMIT, 10, Tick.ask - i * Offset, 0, 0, 0, NULL, i);

      if (!OrdersSell[i])
        OrderSend(Symb, OP_SELLLIMIT, 10, Tick.bid + i * Offset, 0, 0, 0, NULL, i);
      // 
      if (!OrdersBuyStop[i])
        OrderSend(Symb, OP_BUYSTOP, 10, Tick.ask + i * Offset, 0, 0, 0, NULL, i+100);

      if (!OrdersSellStop[i])
        OrderSend(Symb, OP_SELLSTOP, 10, Tick.bid - i * Offset, 0, 0, 0, NULL, i+100);
      
    }  
//检查 TP=SL= 开仓价格的限价订单。
    OrderSend(Symb, OP_BUYLIMIT, 11,  Tick.ask -  Offset, 0,Tick.ask -  Offset, Tick.ask -  Offset, NULL, 1100);
    OrderSend(Symb, OP_SELLLIMIT, 11, Tick.bid +  Offset, 0,Tick.bid +  Offset, Tick.bid +  Offset, NULL, 1100);

//检查限价订单的关闭情况 OrderDelete()
    OrderSend(Symb, OP_BUYLIMIT, 12,  Tick.ask -  Offset, 0,Tick.ask -  Offset, Tick.ask -  Offset, NULL, 1005);
    OrderSend(Symb, OP_SELLLIMIT, 12, Tick.bid +  Offset, 0,Tick.bid +  Offset, Tick.bid +  Offset, NULL, 1005);
      

//TP/SL=偏移的普通订单 将不会被修改,由 TP/SL 触发
    sl=Tick.bid-Offset; tp=Tick.ask+Offset;
    OrderSend(Symb, OP_BUY,  0.01, Tick.ask, 0, sl, tp,  NULL, 1000);//
    sl=Tick.ask+Offset; tp=Tick.bid-Offset;
    OrderSend(Symb, OP_SELL, 0.1, Tick.bid, 0, sl, tp,  NULL, 1000);//

//проверка ТП/СЛ на границе спреда. В виртуальном тестере - ок. У тестера MQ бывают сбои на 1-х сделках теста https://www.mql5.com/ru/forum/455977/page36#comment_51246904&nbsp;&nbsp; и   https://www.mql5.com/ru/forum/455977/page36#comment_51248196
    OrderSend(Symb, OP_BUY,  10, Tick.ask, 0, Tick.bid, Tick.bid,  NULL, 1000);//TP/SL在传播边界 
    OrderSend(Symb, OP_SELL, 10, Tick.bid, 0, Tick.ask, Tick.ask,  NULL, 1000);//TP/SL在传播边界 
  
//检查 OrderClose() 是否已完全关闭
    OrderSend(Symb, OP_BUY,  10, Tick.ask, 0, 0, 0,  NULL, 1001);
    OrderSend(Symb, OP_SELL, 10, Tick.bid, 0, 0, 0,  NULL, 1001);


    //检查部分关闭 OrderClose() 
    sl=Tick.bid-Offset; tp=Tick.ask+Offset;
    OrderSend(Symb, OP_BUY,  10, Tick.ask, 0, 0, 0,  NULL, 1002);
    sl=Tick.ask+Offset; tp=Tick.bid-Offset;
    OrderSend(Symb, OP_SELL, 10, Tick.bid, 0, 0, 0,  NULL, 1002);// 

  }
}

服务器:MetaQuotes-Demo Hedge

处理第二页上的第 99 票。

 

Этот отчет показал Firefox. Chrome зависает, ему нужны файлы поменьше.

可以向文件上传超过 540 万行的内容,但 Firefox 浏览器无法处理更多内容。

在加载这份报告时,浏览器使用了大约 6GB 内存(处理了大约 1 分钟),然后释放了内存,之后报告就显示在页面上了:(80-100k 行的报告使用了 5-6GB 内存)。

不知道其他浏览器的情况如何。

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

错误、错误、问题

fxsaber, 2023.10.18 15:00

打开大型 HTML 表格时的最快浏览器评级 - steutments.35K 行表格的汇总结果。

浏览器 时长(秒)
我的钱包 24
Basilisk 35
苍月 50
K-Meleon 52
55

我的明确选择是MyPal

 
fxsaber #:
我的理解是否正确,目前的实施要求您必须在线才能使用highcharts

是的,如果 JS 文件下载较早,则会从缓存中删除。
存储1个月:1月8日下载,2月8日删除


我想快速将他们的代码添加到文件中,但有成千上万个引号,自动改为\"""。但是弹出了一个错误。它不能快速工作。
 
Forester #:

我想快速将他们的代码添加到文件中,但是有成千上万个引号,我自动将其改为了\""。但是弹出了一个错误。我无法快速完成。

快速版本。

Scripts: Balance Graph HTML - How to generate various variants of the Balance Graph.
Scripts: Balance Graph HTML - How to generate various variants of the Balance Graph.
  • 2019.04.09
  • www.mql5.com
But has no possibility of further modification. For example, if you need to get graphs of profits, commissions, turnover, etc. Where can i generate various variants of the graph. I pasted your html code into my library
 

QuickReport 在顶部,Report 在底部。第二种只对触发水平进行颜色高亮显示。因此,可以理解为触发了 SL 或 TP。我会将其添加到快速报告中。

 
fxsaber #:

QuickReport 在顶部,Report 在底部。第二种只对触发水平进行颜色高亮显示。因此可以理解为触发了 SL 或 TP。我会将其添加到快速报告中。

TP 和 SL 都会突出显示,因为两者都设置在同一价格。这种情况很少见(仅用于极端状态测试),但为了准确起见,我添加了代码来检测并突出显示这种情况。

Forester#:
我想快速将其代码添加到文件中,但是有成千上万的引号,我自动将其改为\""。但是弹出了一个错误。这样做并不快。

我改变了在文件中添加代码的想法,因为这需要许可证。更多信息请点击这里https://shop.highcharts.com/
我默认设置了google. charts ,如果有人需要Highcharts 并拥有使用权,可以通过它来加入:

// 默认情况下,MT4Orders_QuickReport 使用免费的 google.charts,但如果您有权限,也可以使用 highcharts。
// #define USE_highcharts // 您可以免费下载并试用所有 Highcharts 产品。一旦您的项目/产品准备就绪,即可购买商业许可证。https://shop.highcharts.com/。
 
Forester #:

TP 和 SL 都被高亮显示,因为两者都设置为相同的价格。这种情况很少见(仅用于极端状态测试),但为了准确起见,我还是添加了代码,以便在这种情况下也能检测和高亮显示。

一个有趣的案例揭示了与 MQ 测试仪的另一个不同之处。


这是虚拟。


这是 MQ-Tester。

Virtual 在 SL 上关闭了两个仓位,MQ 在 SL 上关闭了两个仓位,MQ 在 SL 上关闭了两个仓位,MQ 在 SL 上关闭了两个仓位。虚拟有特别规定的 SL 平仓优先权。MQ - 未知。

 
fxsaber #:

这是一个有趣的案例,它揭示了 MQ Tester 的另一个不同之处。

这是虚拟的。

这是 MQ-Tester。

Virtual 通过 SL 平仓,而 MQ 则以不同的方式平仓。Virtual特别规定了SL平仓的优先级。MQ - 未知。

是的,我也注意到了。也许 MQ 取决于买入和卖出的方向,哪个先起作用。