MQL4 및 MQL5에 대한 초보자 질문, 알고리즘 및 코드에 대한 도움말 및 토론 - 페이지 522

 
PolarSeaman :

이 얼마나 반전!)))

주문 1(from# 없음, to#2) --> Order2(from#1, to#3) -->Order3(from#2, to# 없음)

이를 기반으로 전체 체인을 찾을 수 있습니다.

열린 댓글을 살펴보고 from#XXX가 있는 경우 이전에 부분적으로 닫혔습니다. 댓글에서 티켓 XXX를 보고 기록에서 찾습니다. 거기에 있는 댓글을 봅니다. from#YYY가 있는 경우 - 이전에도 부분적으로 닫혔습니다. - 댓글에서 YYY 티켓을 보고 기록에서 찾습니다. 우리는 거기에 있는 주석을 봅니다. from#ZZZ가 있는 경우 - 이는 또한 이전에 부분적으로 닫혔음을 의미합니다. - 검색을 반복합니다. from#...이 없으면 전체 체인의 맨 처음입니다.

 
Artyom Trishkin :

주문 1(from# 없음, to#2) --> Order2(from#1, to#3) -->Order3(from#2, to# 없음)

이를 기반으로 전체 체인을 찾을 수 있습니다.

열린 댓글을 살펴보고 from#XXX가 있는 경우 이전에 부분적으로 닫혔습니다. 댓글에서 티켓 XXX를 보고 기록에서 찾습니다. 거기에 있는 댓글을 봅니다. from#YYY가 있는 경우 - 이전에도 부분적으로 닫혔습니다. - 댓글에서 YYY 티켓을 보고 기록에서 찾습니다. 우리는 거기에 있는 주석을 봅니다. from#ZZZ가 있는 경우 - 이는 또한 이전에 부분적으로 닫혔음을 의미합니다. - 검색을 반복합니다. from#...이 없으면 전체 체인의 맨 처음입니다.

감사합니다. 반대 방향의 주문이 있을 수 있습니다. 이것도 파쇄하겠습니다. 헷갈릴까봐. 부분청산을 하면 날짜가 바뀌기 때문에 포지션이 언제 열렸 는지 알 수 있다면 물론 특정 날짜부터 Profit Closed 기능을 사용하는 것이 더 쉬울 거라고 생각합니다

 
Artyom Trishkin :

주문 1(from# 없음, to#2) --> Order2(from#1, to#3) -->Order3(from#2, to# 없음)

이를 기반으로 전체 체인을 찾을 수 있습니다.

열린 댓글을 살펴보고 from#XXX가 있는 경우 이전에 부분적으로 닫혔습니다. 댓글에서 티켓 XXX를 보고 기록에서 찾습니다. 거기에 있는 댓글을 봅니다. from#YYY가 있는 경우 - 이전에도 부분적으로 닫혔습니다. - 댓글에서 YYY 티켓을 보고 기록에서 찾습니다. 우리는 거기에 있는 주석을 봅니다. from#ZZZ가 있는 경우 - 이는 또한 이전에 부분적으로 닫혔음을 의미합니다. - 검색을 반복합니다. from#...이 없으면 전체 체인의 맨 처음입니다.

Artyom, 항상 그런 것은 아닙니다. 그리고 체인을 추적하는 동안 터미널에 세 번 묻지 않기 위해 히스토리는 여전히 배열과 구조로 구동됩니다. 불필요한 작업을 제외하고는 자체 데이터베이스를 유지 관리하는 것과 다르지 않습니다.

터미널 및 해당 API는 가능한 가장 낮은 수준입니다. 그리고 로봇의 논리를 구현하려면 해당 용어(거래, 체인, 그룹, 거래 - 모두가 다르게 부른다)로 기록을 유지하는 것이 논리적입니다. 일부 논리적으로 완료된 일련의 작업. 재채기할 때마다 복원하려고 하지 않고 별도로 유지하는 것이 현명합니다(틱/바).

 
Maxim Kuznetsov :

Artyom, 항상 그런 것은 아닙니다. 그리고 체인을 추적하는 동안 터미널에 세 번 묻지 않기 위해 히스토리는 여전히 배열과 구조로 구동됩니다. 불필요한 작업을 제외하고는 자체 데이터베이스를 유지 관리하는 것과 다르지 않습니다.

터미널 및 해당 API는 가능한 가장 낮은 수준입니다. 그리고 로봇의 논리를 구현하려면 해당 용어(거래, 체인, 그룹, 거래 - 모두가 다르게 부른다)로 기록을 유지하는 것이 논리적입니다. 일부 논리적으로 완료된 일련의 작업. 재채기할 때마다 복원하려고 하지 않고 별도로 유지하는 것이 현명합니다(틱/바).

나는 이 모든 일을 오랫동안 해왔습니다. 매번 이야기를 읽지는 않습니다. 하지만 항상 최신 정보를 제공하며 필요한 모든 것을 쉽고 빠르게 찾을 수 있습니다. 하지만 누군가에게 똑같이 하라고 조언하기 위해서는 적어도 몇 편의 기사를 작성해야 합니다. 그래서 전체 체인을 찾는 논리를 그렸습니다.

 
PolarSeaman :

감사합니다. 반대 방향의 주문이 있을 수 있습니다. 이것도 파쇄하겠습니다. 헷갈릴까봐. 특정 날짜부터 Profit Closed 기능을 사용하는 것이 더 쉬울 거라고 생각합니다만 , 포지션이 언제 열렸 는지 알 수 있다면 포지션이 부분적으로 닫히면 날짜가 바뀌기 때문입니다.

체인을 검색하려면 주문의 티켓, 알고 싶은 전체 체인을 아는 것으로 충분합니다. 티켓을 검색 기능에 매개변수로 전달하고 출력에서 채워진 배열 또는 배열 전체 체인의 각 주문의 모든 데이터가 있는 구조.

 
Artyom Trishkin :

채워진 배열 또는 전체 체인의 각 순서의 모든 데이터가 포함된 구조 배열입니다.

방금 무슨 말을 했는지도 모르겠습니다.

그것이 어떻게 되어야 하는지에 대한 최소한의 예를 보여주십시오.

 
PolarSeaman :

방금 무슨 말을 했는지도 모르겠습니다.

그것이 어떻게 되어야 하는지에 대한 최소한의 예를 보여주십시오.

나는 다음과 같은 방법으로 문제를 해결한다. 나는 역사로 사슬을 찾는다. 글쎄, 기록에 명확하게 액세스할 수 있도록 하기 위해 두 가지 옵션을 사용합니다.

  1. DLL이 없으면 프로그램 설명에서 굵게 24)))) 계정 기록이 항상 전체로 로드되어야 함을 나타냅니다("터미널" 창의 "계정 기록" 탭, 상황에 맞는 메뉴 - "모든 기록"). .
  2. DLL을 사용하면 Expert Advisor 자체가 사용자 작업에 관계없이 "계정 기록" 탭을 최신 상태로 유지합니다.

현재 주문이 기본 주문이 아닌 경우 상위 주문을 결정하는 기능:

 int GetSignOfPartialOrCloseByClose()
{
   string comment = OrderComment ();
   if (comment == "" )
       return 0 ;
   
   // Ордер образовался вследствии частичного закрытия
   int fromStart = StringFind (comment, "from #" );
   if (fromStart >= 0 )
       return GetTicketByPartialClose(comment, fromStart, OrderType (), OrderOpenTime ());
   
   // Ордер образовался вследствии встречного закрытия
   if ( StringFind (comment, "partial close" ) >= 0 )
   {
       datetime openTime = OrderOpenTime ();
       int type = OrderType ();
       for ( int i = OrdersHistoryTotal () - 1 ; i >= 0 ; i--)
      {
         if (! OrderSelect (i, SELECT_BY_POS , MODE_HISTORY ))
             continue ;
            
         if ( OrderOpenTime () != openTime)
             continue ;
            
         if ( OrderType () != type)
             continue ;
            
         if ( StringFind ( OrderComment (), "partial close" ) < 0 )
             continue ;
            
         return OrderTicket ();
      }
   }
   
   return 0 ;
}


int GetTicketByPartialClose( string comment, int fromStart, int orderType, datetime openTime)
{
   string sTicket = StringSubstr (comment, fromStart + 6 );
   int iTicket = ( int ) StringToInteger (sTicket);
   int type = OrderType ();
   if (! OrderSelect (iTicket, SELECT_BY_TICKET ))
       return 0 ;
      
   if ( OrderType () == type)                                                                         // Дочерний ордер указывает на родителя - уходим
       return iTicket;
      
   // Дочерний ордер указывает на противоположный ордер. Необходимо искать родительский
   for ( int i = OrdersHistoryTotal () - 1 ; i >= 0 ; i--)
   {
       if (! OrderSelect (i, SELECT_BY_POS , MODE_HISTORY ))
         continue ;
         
       if ( OrderType () != orderType || OrderOpenTime () != openTime)
         continue ;
         
       int iFind = StringFind ( OrderComment (), "close hedge by #" );
       if (iFind < 0 )
         continue ;
         
      sTicket = StringSubstr ( OrderComment (), iFind + 16 );
       int iNewTicket = ( int ) StringToInteger (sTicket);
       if (iNewTicket != iTicket)
         continue ;
         
       return OrderTicket ();
   }
   
   return 0 ;
}

사용 방법은 간단합니다.

   for ( int i = OrdersTotal () - 1 ; i >= 0 ; i--)
   {
       if (! OrderSelect (i, SELECT_BY_POS ))
         continue ;

      ....         

       int nFromTicket = GetSignOfPartialOrCloseByClose();                 // Обязательно последней строкой в теле цикла, т. к. может измениться текущий выбранный ордер
   }


 
Ihor Herasko :

여기서 가장 심각한 실수는 OrderDelete() 함수의 인수에 티켓 대신 값 100을 지정하는 것입니다.

또한 오류가 그렇게 거칠지는 않지만 실제 값이 아닌 계산된 손절매 값을 확인한다는 사실과 관련이 있습니다.

주문 유형이 아직 확인되지 않았습니다. 갑자기 시장가 주문을 선택? 그럼 어떻게 제거할까요? 주문 기호가 선택되지 않았습니다.

이러한 오류를 고려하여 가격이 손절매에 도달할 때 보류 중인 주문을 삭제하기 위해 다음 코드를 얻습니다.

또한 코드에서 손절매는 주문을 연 직후에 확인됩니다. 보류 중인 주문을 연 후 이 코드는 더 이상 실행되지 않는 것 같습니다. 즉, 실행 분기를 분리해야 합니다. 하나는 주문을 담당하고 두 번째는 지원을 담당합니다.

자세한 답변 정말 감사합니다!

당신의 조언에 따라 가지를 나누었고 모든 것이 밝혀졌습니다.

그런 다음 10-15개의 보류 주문을 동시에 여는 문제에 부딪쳤습니다. 코드 뒤에 추가하여 문제를 해결했습니다.

 if ( OrdersTotal ()> 0 ) return ;

더 현명한 방법이 있다고 확신합니다.

코드에 따르면 1이 무엇을 의미하는지 설명하지 마십시오. 나는 >=0; --나 ?

 for ( int i = OrdersTotal () - 1 ; i >= 0 ; --i)
 

지표를 작성하는 방법을 알아낼 수 있도록 도와주세요. 여기에서 나는 그러한 공백을 스케치했는데, 표시가 차트에 배치 되는 순간부터 시작 하여 현재 입찰가보다 위에 그려진 크기 포인트가 될 긴 길이 의 표시 선을 표시하도록 만드는 방법은 무엇입니까? 아마도 오류가 이 배열을 잘못된 방향으로 이동하고 있다는 것입니까?

나는 이것이 prev_calculated 및 기타 사항 없이 "canon"에 따른 것임을 알고 있지만 다음과 같이 필요합니다.


#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link        "https://www.mql5.com"
#property version    "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//---- plot 
#property indicator_label1    "myInd"
#property indicator_type1    DRAW_LINE
#property indicator_color1   Blue
#property indicator_style1    STYLE_SOLID
#property indicator_width1    1

double buff[], Bid ;
input int lenght = 50 , size = 5 ;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit ()
  {
//--- indicator buffers mapping

   ArrayResize (buff, 50 );
   ArrayInitialize (buff, 0 );
   SetIndexBuffer ( 0 , buff, INDICATOR_DATA );
   //--- установим метку для отображения в DataWindow
   PlotIndexSetString ( 0 , PLOT_LABEL , "myInd" );   
//--- установим имя для показа в отдельном подокне и во всплывающей подсказке
   IndicatorSetString ( INDICATOR_SHORTNAME , "myInd" );
//--- укажем точность отображения значений индикатора
   IndicatorSetInteger ( INDICATOR_DIGITS , _Point );
//---
   return ( INIT_SUCCEEDED );
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate ( const int rates_total,
                 const int prev_calculated,
                 const datetime &time[],
                 const double &open[],
                 const double &high[],
                 const double &low[],
                 const double &close[],
                 const long &tick_volume[],
                 const long &volume[],
                 const int &spread[])
  {
//---
   Bid = SymbolInfoDouble ( _Symbol , SYMBOL_BID );
   for ( int i = lenght- 1 ; i> 0 ; i--){
      buff[i] = buff[i- 1 ];
   }
   buff[ 0 ] = Bid +size;
   


   
//--- return value of prev_calculated for next call
   return (rates_total);
  }
//+------------------------------------------------------------------+
 
Roman Sharanov :

지표를 작성하는 방법을 알아낼 수 있도록 도와주세요. 여기에서 나는 그러한 공백을 스케치했는데, 표시가 차트에 배치 되는 순간부터 시작 하여 현재 입찰가보다 위에 그려진 크기 포인트가 될 긴 길이 의 표시 선을 표시하도록 만드는 방법은 무엇입니까? 아마도 오류가 이 배열을 잘못된 방향으로 이동하고 있다는 것입니까?

나는 이것이 prev_calculated 및 기타 사항 없이 "canon"에 따른 것임을 알고 있지만 다음과 같이 필요합니다.


어떤 종류의 캐논입니까? off.doc이 있습니다 - 그것은 당신의 것과 똑같습니다 .. 다른 모든 것은 사악한 것입니다.

1. OnCalculate 내부에서 사용된 모든 배열의 직렬성을 설정합니다.

2. 루프에 들어가기 전에 버프[길이]=입찰가+크기를 설정하십시오. - 원하는 대로 정확하게 나타납니다. 입찰가 + 크기 수준에서 곡선 및 "바이저" 끝

3. 배열 경계에 주의하십시오. 물론 rate_total < 길이는 거의 없지만 농담이 아닙니다 :-)

4.
buff[i] = buff[i+ 1 ]; // если тайм-серия (а вы подразумеваете их) то +