mql5 언어의 특징, 미묘함 및 작업 방법 - 페이지 3

 
fxsaber :

거래 스크립트에는 어떤 OnTradeTransaction이 포함될 수 있습니까? 귀하의 코드가 아니라 다른 사람의 거래 스크립트에 있습니다.
본격적인 거래 로봇이 스크립트로 작성될 수 있다고 진지하게 믿습니까?
 
친구, 주제에 더 가까이 다가가십시오. 하나 또는 다른 명령문 구현의 예를보고 싶습니다. 코드가 반드시 필요한 것은 아닙니다. 코드가 많은 경우 논리를 설명할 수 있습니다. 예를 들어 요청이 전송되었는지 확인하기 위해 요청을 보내고 그곳을 살펴보고 이러한 반환 코드를 받으면 수행합니다. 이것. 즉, 가장 신뢰할 수 있는 데이터 수집의 예입니다.

그런 다음 우리가 맹세하면 논쟁의 여지가 있습니다. 유용한 주제에서 우리는 논쟁의 여러 페이지로 넘어갈 것입니다. 그런 다음 본질이 남도록 모든 것을 청소하십시오 ... 이것이 바로 여기에 표시되는이 또는 그 과정의 본질입니다. 어떤 구현을 위한 몇 가지 옵션이 있습니다. 각 방법의 장점과 단점에 대해 논의합니다.

그러다가 서로 다른 유용한 정보가 충분히 쌓이면 이 모든 것을 태블릿에 모아보자는 아이디어가 떠올랐다. 그리고 정기적으로 유용한 칩을 축적하여 지속적으로 보충하십시오.
나는 그것이 모두에게 유용할 것이라고 생각합니다.
 
질문 : 숫자를 8진수 및 16진수 시스템으로 변환하는 방법.

대답:
하나.

거래, 자동 거래 시스템 및 거래 전략 테스트에 관한 포럼

8 및 16 리차

타라스 슬로보디아닉 , 2017.02.24 22:16

string DecToHex( int n)
  {
   string s = "" , c;
   while (n != 0 )
     {
       if (n% 16 < 10 )
         c= CharToStr (n% 16 + '0' );
       else
         c= CharToStr (n% 16 + 'A' - 10 );
      s = c + s;
      n = n / 16 ;
     }
   return (s);
  }
2.

거래, 자동 거래 시스템 및 거래 전략 테스트에 관한 포럼

8 및 16 리차

막심 쿠즈네초프 , 2017.02.24 22:20

갑자기 StringFormat, PrintFormat :-)

PrintFormat("16진수 %x 및 8진수 %o",1122,1122);
삼.

거래, 자동 거래 시스템 및 거래 전략 테스트에 관한 포럼

8 및 16 리차

fxsaber , 2017.02.24 22:21

string NumToString( uint Num, const uint Scale = 10 )
{
   static const string digits[] = { "0" , "1" , "2" , "3" , "4" , "5" , "6" , "7" , "8" , "9" ,
                                   "A" , "B" , "C" , "D" , "E" , "F" , "G" , "H" , "I" , "K" ,
                                   "L" , "M" , "N" , "O" , "P" , "Q" , "R" , "S" , "T" , "V" , "X" , "Y" , "Z" };
  
   string Str = (Num == 0 ) ? "0" : "" ;
  
   while (Num > 0 )
  {
    Str = digits[Num % Scale] + Str;
    
    Num /= Scale;
  }
  
   return (Str);
}

void OnStart ()
{
   Print (NumToString( 123 , 8 ));
   Print (NumToString( 123 , 16 ));
}



 
단순 상인 :
본격적인 거래 로봇이 스크립트로 작성될 수 있다고 진지하게 믿습니까?
할 수 있다
 
알렉세이 코지친 :

동지 fxsaber와 prostotrader에 대한 논의를 별도의 스레드로 옮기십시오. 여기에 논의가 있으면 스레드는 실질적인 의미를 잃게 됩니다. 실제 솔루션이 나오면 여기에 씁니다. 그리고 저는 이것이 의심이나 연구의 한 분야가 되어서는 안 된다고 믿습니다. 이것은 실용적인 솔루션의 한 분야여야 합니다. 그리고 여러 사람이 문제에 대해 서로 다른 비전을 갖고 있다면 다른 곳에서 토론하게 하십시오.

<삭제할 글>

진실을 찾도록 합시다. 그것에 대해 생각할 시간이 있었고 나는 그것을 떠나기로 결정했고 내가 묻고 내 의심을 풀어달라고 요청한 Vitya (Vinin)도 토론을 떠나겠다고 제안했습니다 (제거에서 내 의심을 확인)-진실을 그대로 두십시오 태어난. 그게 더 정확할 것 같아요. 아무튼 차후에는 여기다가 채워서 적용할 수 있도록 타블렛에 모으기 시작하려고 합니다.
 
단순 상인 :

몇 밀리초를 기다릴 필요가 없습니다.

메시지가 OnTradeTransaction 으로 전송됩니다.

코드 참조

당신의 메시지의 의미는 무엇입니까? 글쎄, 그것은 OnTradeTransaction()에 올 것이다, 그래서 무엇? 즉, 이벤트를 기다려야 합니다. 아직 기다리고 있습니다. fxsaber 메시지의 의미는 OrderSend() 실행 후 수행된 작업에 대한 정보가 터미널에 즉시 나타나지 않는다는 것입니다. 누군가는 OnTradeTransaction()을 기다리는 것을 좋아하고 누군가는 목록에 있는 주문이나 거래의 출현을 좋아합니다. 예를 들어 MT4와의 차이점. M4에서 OrderSend() 이후 주문은 이미 주문 목록에 있고 OrderClose() 이후에는 항상 기록에 있습니다.

 
Artyom Trishkin :
진실을 찾도록 합시다. 그것에 대해 생각할 시간이 있었고 나는 그것을 떠나기로 결정했고 내가 묻고 내 의심을 풀어달라고 요청한 Vitya (Vinin)도 토론을 떠나겠다고 제안했습니다 (제거에서 내 의심을 확인)-진실을 그대로 두십시오 태어난. 그게 더 정확할 것 같아요. 아무튼 차후에는 여기다가 채워서 적용할 수 있도록 태블릿에 모으기 시작하려고 합니다.
진실은 prototrader와의 분쟁에서 발생할 수 없으며, 그는 이것을 위해 시작하지 않습니다. 언제나처럼 그는 대화 내용에 대해서는 입력조차 하지 않았습니다.
 
여기서 논란이 되는 것은? 여기에는 논쟁의 여지가 없습니다. fxsaber는 실제로 문서화되지 않고 모든 사람이 알아야 하는 터미널의 한 기능에 대해 상기시켰습니다. 그렇지 않으면 Expert Advisors의 개발에 문제가 있을 것이며 검색하고 분류해야 합니다.
 
Artyom Trishkin :
진실을 찾자...

아르툼!

당신은 똑똑하고 정치적으로 올바른 사람입니다!

무슨 진실? 문제가 무엇인지 완벽하게 이해하고 있습니다.

fxsaber는 스크립트를 작성했지만(나쁘지는 않음) 아무도 그를 칭찬하지 않았으므로 여기에 있습니다.

모든 주제에서 그것에 대해 상기시키려고 노력합니다.

칭찬 - 잘했어!

그러나 문제는 이 스크립트에서 OnTradeTransaction을 사용할 수 없기 때문에 "Mr."에서 공을 굴려야 한다는 것입니다(예: Sleep 또는 다른 타이머).

그리고 물론 SCRIPT가 ADVISOR보다 낫다는 것을 아직 모르는 다른 사용자를 위한 "관리"!

그리고 Dmitry Fedoseev 는 항상 내가 말하는 것에 대해 선험적이며 내가 옳고 그름은 중요하지 않습니다.

진실은 여기에서 찾을 수 없습니다. 왜냐하면 그것은 비즈니스가 아니라 개인이기 때문입니다.

 
class ORDERSEND  
{
private :
   static const bool IsTester;
  
   static bool Waiting( const bool FlagInit = false )
  {
     static ulong StartTime = 0 ;

     const bool Res = FlagInit ? false : (:: GetMicrosecondCount () - StartTime < ORDERSEND::OrderSend_MaxPause);

     if (FlagInit)
      StartTime = :: GetMicrosecondCount ();
     else if (Res)
      :: Sleep ( 0 );

     return (Res);
  }

   static bool EqualPrices( const double Price1, const double Price2, const int digits)
  {
     return (:: NormalizeDouble (Price1 - Price2, digits) == 0 );
  }

   static bool HistoryDealSelect ( MqlTradeResult &Result )
  {
     if ((Result.deal == 0 ) && (Result.order != 0 ))
    {
       if (:: HistorySelectByPosition (:: HistoryOrderGetInteger (Result.order, ORDER_POSITION_ID )))
         for ( int i = :: HistoryDealsTotal () - 1 ; i >= 0 ; i--)
        {
           const ulong DealTicket = :: HistoryDealGetTicket (i);

           if (Result.order == :: HistoryDealGetInteger (DealTicket, DEAL_ORDER ))
          {
            Result.deal = DealTicket;

             break ;
          }
        }
    }

     return (:: HistoryDealSelect (Result.deal));
  }

#define TMP_ORDERSEND_BENCHMARK(A) \
   static ulong Max ##A = 0 ;         \
                                   \
   if (Interval ##A > Max ##A)         \
  {                                \
    ORDERSEND_BENCHMARK            \
                                   \
    Max ##A = Interval ##A;           \
  }

   static void OrderSend_Benchmark( const ulong Interval1, const ulong Interval2 = 0 )
  {
     #ifdef ORDERSEND_BENCHMARK
      TMP_ORDERSEND_BENCHMARK( 1 )
      TMP_ORDERSEND_BENCHMARK( 2 )
     #endif // ORDERSEND_BENCHMARK

     return ;
  }

#undef TMP_ORDERSEND_BENCHMARK

#define WHILE(A) while ((!(Res = (A))) && ORDERSEND::Waiting())

public :
   static uint OrderSend_MaxPause; // максимальное время на синхронизацию в мкс.
  
   // Полностью синхронизированный с торговым окружением OrderSend.
   // По окончании работы ГАРАНТИРОВАННО и за МИНИМАЛЬНОЕ время доступно корректное торговое окружение.
   // По скорости ничем не уступает связке OrderSendAsync + OnTradeTransaction.
   // Учтены MT5-нюансы: Result.deal == 0, STATE_STARTED и STATE_MODIFY pending.
   // В тестере/оптимизаторе производительность равна штатной OrderSend.

   static bool OrderSendSync( const MqlTradeRequest &Request, MqlTradeResult &Result )
  {
     const ulong StartTime1 = :: GetMicrosecondCount ();

     bool Res = :: OrderSend (Request, Result);

     const ulong Interval1 = :: GetMicrosecondCount () - StartTime1;

     const ulong StartTime2 = :: GetMicrosecondCount ();

     if (Res && !ORDERSEND::IsTester && (Result.retcode < TRADE_RETCODE_ERROR ) && (ORDERSEND::OrderSend_MaxPause > 0 ))
    {
      Res = (Result.retcode == TRADE_RETCODE_DONE );
      ORDERSEND::Waiting( true );

       if (Request.action == TRADE_ACTION_DEAL )
      {
        WHILE(:: HistoryOrderSelect (Result.order))
          ;

        Res = Res && ((( ENUM_ORDER_STATE ):: HistoryOrderGetInteger (Result.order, ORDER_STATE ) == ORDER_STATE_FILLED ) ||
                      (( ENUM_ORDER_STATE ):: HistoryOrderGetInteger (Result.order, ORDER_STATE ) == ORDER_STATE_PARTIAL ));

         if (Res)
          WHILE(ORDERSEND:: HistoryDealSelect (Result))
            ;
      }
       else if (Request.action == TRADE_ACTION_PENDING )
      {
         if (Res)
          WHILE(:: OrderSelect (Result.order) && (( ENUM_ORDER_STATE ):: OrderGetInteger ( ORDER_STATE ) == ORDER_STATE_PLACED ))
            ;
         else
        {
          WHILE(:: HistoryOrderSelect (Result.order))
            ;

          Res = false ;
        }
      }
       else if (Request.action == TRADE_ACTION_SLTP )
      {
         if (Res)
        {
           bool EqualSL = false ;
           bool EqualTP = false ;

           const int digits = ( int ):: SymbolInfoInteger (Request.symbol, SYMBOL_DIGITS );

           if ((Request.position == 0 ) ? :: PositionSelect (Request.symbol) : :: PositionSelectByTicket (Request.position))
          {
            EqualSL = ORDERSEND::EqualPrices(:: PositionGetDouble ( POSITION_SL ), Request.sl, digits);
            EqualTP = ORDERSEND::EqualPrices(:: PositionGetDouble ( POSITION_TP ), Request.tp, digits);
          }

          WHILE((EqualSL && EqualTP))
             if ((Request.position == 0 ) ? :: PositionSelect (Request.symbol) : :: PositionSelectByTicket (Request.position))
            {
              EqualSL = ORDERSEND::EqualPrices(:: PositionGetDouble ( POSITION_SL ), Request.sl, digits);
              EqualTP = ORDERSEND::EqualPrices(:: PositionGetDouble ( POSITION_TP ), Request.tp, digits);
            }
        }
      }
       else if (Request.action == TRADE_ACTION_MODIFY )
      {
         if (Res)
        {
           bool EqualSL = false ;
           bool EqualTP = false ;
           bool EqualPrice = false ;

           const int digits = ( int ):: SymbolInfoInteger (Request.symbol, SYMBOL_DIGITS );

           if (:: OrderSelect (Result.order))
          {
            EqualSL = ORDERSEND::EqualPrices(:: OrderGetDouble ( ORDER_SL ), Request.sl, digits);
            EqualTP = ORDERSEND::EqualPrices(:: OrderGetDouble ( ORDER_TP ), Request.tp, digits);
            EqualPrice = ORDERSEND::EqualPrices(:: OrderGetDouble ( ORDER_PRICE_OPEN ), Request.price, digits);
          }

          WHILE((EqualSL && EqualTP && EqualPrice))
             if (:: OrderSelect (Result.order) && (( ENUM_ORDER_STATE ):: OrderGetInteger ( ORDER_STATE ) != ORDER_STATE_REQUEST_MODIFY ))
            {
              EqualSL = ORDERSEND::EqualPrices(:: OrderGetDouble ( ORDER_SL ), Request.sl, digits);
              EqualTP = ORDERSEND::EqualPrices(:: OrderGetDouble ( ORDER_TP ), Request.tp, digits);
              EqualPrice = ORDERSEND::EqualPrices(:: OrderGetDouble ( ORDER_PRICE_OPEN ), Request.price, digits);
            }
        }
      }
       else if (Request.action == TRADE_ACTION_REMOVE )
         if (Res)
          WHILE(:: HistoryOrderSelect (Result.order))
            ;
    }

     const ulong Interval2 = :: GetMicrosecondCount () - StartTime2;

    Result.comment += " " + :: DoubleToString (Interval1 / 1000.0 , 3 ) + " + " + :: DoubleToString (Interval2 / 1000.0 , 3 ) + " ms" ;

    ORDERSEND::OrderSend_Benchmark(Interval1, Interval2);

     return (Res);
  }

#undef WHILE
};

static const bool ORDERSEND::IsTester = (:: MQLInfoInteger ( MQL_TESTER ) || :: MQLInfoInteger ( MQL_OPTIMIZATION ) ||
                                         :: MQLInfoInteger ( MQL_VISUAL_MODE ) || :: MQLInfoInteger ( MQL_FRAME_MODE ));

static uint ORDERSEND::OrderSend_MaxPause = 1000000 ; // максимальное время на синхронизацию в мкс.

// Эта строчка позволяет сделать все OrderSend корректными.
#define OrderSend ORDERSEND::OrderSendSync

모든 것은 잠재적인 문제를 줄이기 위해 특별히 클래스에 래핑됩니다.

애플리케이션

OrderSend (Request, Result); // Все так же, как со штатной OrderSend

저것들. 모든 OrderSend 를 거래 환경과 동기화하고 함정을 피하려면 주어진 소스를 mqh 파일로 정렬하고 프로그램에 적절한 #include를 만드는 것으로 충분합니다.

사유: