라이브러리: MT4Orders 퀵리포트 - 페이지 4

 
Forester #:

MQ 테스터는 삭제된 지정가 주문을 지연된 상태로 아카이브로 전송하는 것으로 나타났습니다:

재현을 위해 데이터를 제공해 주세요.
 
Forester #:

저는 highchart로 변경했습니다. google.charts는 70만 개의 거래에서 멈췄지만, highchart는 특별한 브레이크 없이 거래가 표시되고 개별 거래를 확대할 수 있어 더 나은 것으로 나타났습니다.

현재 구현에서 highcharts는 온라인 상태여야 한다는 것이 맞나요?
 
fxsaber #:
재생산을 위한 데이터를 제공하세요.
 // 와의 차이점 - #define VIRTUAL_TESTER 대신 SelectByIndex()를 통해 가상 테스터를 연결합니다.
 
 #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));}//현재 시간(시간 단위) 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){//1차 로트 - 25% 마감
               double LotsDel1=NormalizeDouble(Lots/4, 2);// 원래 로트의 25% 닫기
               OrderClose(OrderTicket(), LotsDel1, (OrderType()==OP_BUY ? Tick.bid : Tick.ask), 0 ) ;//부분 폐쇄 확인
           }else{ // 다음 틱에 잔액을 닫습니다.
              OrderClose(OrderTicket(), Lots, (OrderType()==OP_BUY ? Tick.bid : Tick.ask), 0 ) ;//완전히 닫혔는지 확인
           }
         }
            
         //같은 틱에서 주문 닫기()의 부분 청산을 확인합니다. 가상 테스터에서는 작동하지 않습니다. 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);

// 지정가 주문 청산 확인 주문 삭제()
    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 
  
//주문 닫기()가 완전히 닫혔는지 확인합니다.
    OrderSend(Symb, OP_BUY,  10, Tick.ask, 0, 0, 0,  NULL, 1001);
    OrderSend(Symb, OP_SELL, 10, Tick.bid, 0, 0, 0,  NULL, 1001);


    //부분 폐쇄 확인 주문 닫기() 
    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);// 

  }
}

서버: 메타쿼츠-데모 헤지

두 번째 페이지에서 티켓 99를 거래하세요.

 

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

540만 개 이상의 줄을 파일에 업로드할 수 있지만 Firefox 브라우저는 더 이상 처리할 수 없습니다.

이 보고서를 로드할 때 브라우저는 약 6GB의 메모리를 사용한 후(약 1분 처리) 메모리를 비운 후 페이지에 보고서가 표시됩니다(보고서는 8~10만 줄에서 5~6GB 사용).

다른 브라우저에서는 어떤지 궁금합니다.

트레이딩, 자동 트레이딩 시스템 및 테스트 트레이딩 전략에 관한 포럼

버그, 버그, 질문

fxsaber, 2023.10.18 15:00

대형 HTML 테이블을 열 때 가장 빠른 브라우저의 등급 - steutments. 35K 행이 있는 테이블에 대한 요약 결과입니다.

브라우저 길이 시간(초)
MyPal 24
Basilisk 35
PaleMoon 50
K-멜레온 52
토륨 55

저의 확실한 선택은 MyPal입니다.

 
fxsaber #:
현재 구현에서 하이차트가 작동하려면 온라인 상태여야 한다는 것이 제 이해가 맞나요?

예. 또는 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는 상단에, 보고서는 하단에 있습니다. 두 번째는 트리거된 레벨에 대해서만 색상을 강조 표시합니다. 이로 인해 SL 또는 TP가 트리거되었음을 알 수 있습니다. 저는 이 기능을 QuickReport에 추가할 것입니다.

 
fxsaber #:

QuickReport는 상단에, 보고서는 하단에 있습니다. 두 번째는 트리거된 레벨에 대해서만 색상을 강조 표시합니다. 이로 인해 SL 또는 TP가 트리거되었음을 알 수 있습니다. 저는 이 기능을 QuickReport에 추가할 것입니다.

둘 다 같은 가격으로 설정되어 있기 때문에 TP와 SL이 모두 강조 표시됩니다. 이 경우는 드물지만 (극한 상태 테스트에만 해당) 정확성을 위해 그 안에서도 감지하고 강조 표시하는 코드를 추가했습니다.

포레스터 #:
파일에 코드를 빠르게 추가하고 싶었지만 따옴표가 수천 개가 있어서 자동으로 \""로 변경했습니다. 하지만 오류가 발생했습니다. 빨리 작동하지 않았습니다.

라이선스가 필요하기 때문에 파일에 코드를 추가하는 것에 대해 마음을 바꿨습니다. 여기에서 자세히 읽어보세요 https://shop.highcharts.com/
누군가 Highcharts가 필요하고 사용 권한이 있는 경우 기본적으로 google.charts를 설정했습니다:

// 기본적으로 MT4Orders_QuickReport는 무료 google.charts를 사용하지만 권한이 있는 경우 highcharts를 사용할 수 있습니다.
// #define USE_highcharts // 모든 Highcharts 제품을 무료로 다운로드하여 사용해 볼 수 있습니다. 프로젝트/제품을 출시할 준비가 되면 상용 라이선스를 구매하세요. https://shop.highcharts.com/
 
Forester #:

TP와 SL 모두 동일한 가격으로 설정되어 있기 때문에 강조 표시되었습니다. 이 경우는 드물지만(극한 상태 테스트에만 해당) 정확성을 위해 그 안에서도 감지 및 강조 표시 코드를 추가했습니다.

MQ 테스터와의 또 다른 차이점을 드러낸 흥미로운 사례입니다.


이것은 가상입니다.


그리고 이것은 MQ 테스터입니다.

Virtual은 SL에서 두 포지션을 모두 청산했고, MQ는 SL에서 두 포지션을 모두 청산했고, MQ는 SL에서 두 포지션을 모두 청산했고, MQ는 SL에서 두 포지션을 모두 청산했습니다. Virtual은 특별히 규정된 SL 청산 우선순위를 가졌습니다. MQ - 알 수 없음.

 
fxsaber #:

MQ 테스터와 또 다른 차이점을 드러낸 흥미로운 사례입니다.

바로 가상입니다.

그리고 이것은 MQ-Tester입니다.

Virtual은 SL, MQ로 두 포지션을 다른 방식으로 청산했습니다. SL 청산의 우선 순위는 특별히 Virtual에 대해 규정되었습니다. MQ - 알 수 없음.

네, 저도 알아챘습니다. 아마도 MQ는 매수|매도 방향에 따라 무엇이 먼저 작동할지 달라질 수 있습니다.