위대하고 끔찍한 MT4 영원히 (또는 전환 전략을 올바르게 개발하는 방법) - 페이지 23

 

다음과 같이 작동하는 것 같습니다.

 #include <Trade\Trade.mqh>
void OnStart ()
{
   CTrade Trade;
   while ( PositionsTotal () < 10 )
   {
       if ( OrdersTotal () > 0 ) continue ;
       if (!Trade.Buy( 0.01 )) continue ;
       if ( OrdersTotal () == 0 && PositionsTotal () >= 10 ) return ;
   }
}

그러나 매우 천천히, 그리고 해결책은 그저 그렇습니다

 
Igor Makanu :

다음과 같이 작동하는 것 같습니다.

그러나 매우 천천히, 그리고 해결책은 그저 그렇습니다

거의 완료했습니다.

 

일반적으로 서버에서 위치 + 주문 상태를 반환하도록 보장하는 개발자로부터 일종의 동기식 RefreshPositions()가 필요합니다.

그런 다음 필요한 사람은 비동기식으로 명령을 보내고 필요하지 않은 사람은 프로그램 본문에서 서버의 응답을 기다립니다.

 
Ihor Herasko :

그것은 단지 요점, 통과했습니다. 스크립트 실행이 끝난 후 하나 또는 두 개의 위치가 계속 매달려 있습니다(코드에 삽입할 인쇄 수에 따라 다름).

코드:

결과:

그림을 완성하려면 https://www.mql5.com/ru/articles/2513 기사의 거래 이벤트 리스너를 인접한 차트에 추가하십시오.

이벤트 순서를 보려면

 //+------------------------------------------------------------------+
//|                                     TradeTransactionListener.mq5 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link        "https://www.mql5.com"
#property version    "1.00"
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit ()
  {
//---
   PrintFormat ( "LAST PING=%.f ms" ,
               TerminalInfoInteger (TERMINAL_PING_LAST)/ 1000 .);
//---
   return ( INIT_SUCCEEDED );
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick ()
  {
//---

  }
//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction ( const MqlTradeTransaction &trans,
                         const MqlTradeRequest &request,
                         const MqlTradeResult &result)
  {
//---
   static int counter= 0 ;   // счетчик вызовов OnTradeTransaction()
   static uint lasttime= 0 ; // время последнего вызова OnTradeTransaction()
//---
   uint time= GetTickCount ();
//--- если последняя транзакция была больше 1 секунды назад
   if (time-lasttime> 1000 )
     {
      counter= 0 ; // значит, это новая торговая операция и можно сбросить счетчик
       if ( IS_DEBUG_MODE )
         Print ( " Новая торговая операция" );
     }
   lasttime=time;
   counter++;
   Print (counter, ". " , __FUNCTION__ );
//--- результат выполнения торгового запроса
   ulong             lastOrderID   =trans.order;
   ENUM_ORDER_TYPE   lastOrderType =trans.order_type;
   ENUM_ORDER_STATE lastOrderState=trans.order_state;
//--- имя символа, по которому произошла транзакция
   string trans_symbol=trans.symbol;
//--- тип транзакции
   ENUM_TRADE_TRANSACTION_TYPE   trans_type=trans.type;
   switch (trans.type)
     {
       case    TRADE_TRANSACTION_POSITION :   // изменение позиции
        {
         ulong pos_ID=trans.position;
         PrintFormat ( "MqlTradeTransaction: Position  #%d %s modified: SL=%.5f TP=%.5f" ,
                     pos_ID,trans_symbol,trans.price_sl,trans.price_tp);
        }
       break ;
       case TRADE_TRANSACTION_REQUEST :     // отправка торгового запроса
         PrintFormat ( "MqlTradeTransaction: TRADE_TRANSACTION_REQUEST" );
         break ;
       case TRADE_TRANSACTION_DEAL_ADD :     // добавление сделки
        {
         ulong           lastDealID   =trans.deal;
         ENUM_DEAL_TYPE lastDealType =trans.deal_type;
         double         lastDealVolume=trans.volume;
         //--- идентификатор сделки во внешней системе - тикет, присваиваемый Московской биржей
         string Exchange_ticket= "" ;
         if ( HistoryDealSelect (lastDealID))
            Exchange_ticket= HistoryDealGetString (lastDealID, DEAL_EXTERNAL_ID );
         if (Exchange_ticket!= "" )
            Exchange_ticket= StringFormat ( "(MOEX deal=%s)" ,Exchange_ticket);

         PrintFormat ( "MqlTradeTransaction: %s deal #%d %s %s %.2f lot   %s" , EnumToString (trans_type),
                     lastDealID, EnumToString (lastDealType),trans_symbol,lastDealVolume,Exchange_ticket);
        }
       break ;
       case TRADE_TRANSACTION_HISTORY_ADD : // добавление ордера в историю
        {
         //--- идентификатор ордера во внешней системе - тикет, присваиваемый Московской биржей
         string Exchange_ticket= "" ;
         if (lastOrderState== ORDER_STATE_FILLED )
           {
             if ( HistoryOrderSelect (lastOrderID))
               Exchange_ticket= HistoryOrderGetString (lastOrderID, ORDER_EXTERNAL_ID );
             if (Exchange_ticket!= "" )
               Exchange_ticket= StringFormat ( "(MOEX ticket=%s)" ,Exchange_ticket);
           }
         PrintFormat ( "MqlTradeTransaction: %s order #%d %s %s %s   %s" , EnumToString (trans_type),
                     lastOrderID, EnumToString (lastOrderType),trans_symbol, EnumToString (lastOrderState),Exchange_ticket);
        }
       break ;
       default : // прочие транзакции  
        {
         //--- идентификатор ордера во внешней системе - тикет, присваиваемый Московской биржей
         string Exchange_ticket= "" ;
         if (lastOrderState== ORDER_STATE_PLACED )
           {
             if ( OrderSelect (lastOrderID))
               Exchange_ticket= OrderGetString ( ORDER_EXTERNAL_ID );
             if (Exchange_ticket!= "" )
               Exchange_ticket= StringFormat ( "MOEX ticket=%s" ,Exchange_ticket);
           }
         PrintFormat ( "MqlTradeTransaction: %s order #%d %s %s   %s" , EnumToString (trans_type),
                     lastOrderID, EnumToString (lastOrderType), EnumToString (lastOrderState),Exchange_ticket);
        }
       break ;
     }
//--- тикет ордера    
   ulong orderID_result=result.order;
   string retcode_result=GetRetcodeID(result.retcode);
   if (orderID_result!= 0 )
       PrintFormat ( "MqlTradeResult: order #%d retcode=%s " ,orderID_result,retcode_result);
//---   
  }
//+------------------------------------------------------------------+
//| переводит числовые коды ответов в строковые мнемокоды            |
//+------------------------------------------------------------------+
string GetRetcodeID( int retcode)
  {
   switch (retcode)
     {
       case 10004 : return ( "TRADE_RETCODE_REQUOTE" );             break ;
       case 10006 : return ( "TRADE_RETCODE_REJECT" );               break ;
       case 10007 : return ( "TRADE_RETCODE_CANCEL" );               break ;
       case 10008 : return ( "TRADE_RETCODE_PLACED" );               break ;
       case 10009 : return ( "TRADE_RETCODE_DONE" );                 break ;
       case 10010 : return ( "TRADE_RETCODE_DONE_PARTIAL" );         break ;
       case 10011 : return ( "TRADE_RETCODE_ERROR" );               break ;
       case 10012 : return ( "TRADE_RETCODE_TIMEOUT" );             break ;
       case 10013 : return ( "TRADE_RETCODE_INVALID" );             break ;
       case 10014 : return ( "TRADE_RETCODE_INVALID_VOLUME" );       break ;
       case 10015 : return ( "TRADE_RETCODE_INVALID_PRICE" );       break ;
       case 10016 : return ( "TRADE_RETCODE_INVALID_STOPS" );       break ;
       case 10017 : return ( "TRADE_RETCODE_TRADE_DISABLED" );       break ;
       case 10018 : return ( "TRADE_RETCODE_MARKET_CLOSED" );       break ;
       case 10019 : return ( "TRADE_RETCODE_NO_MONEY" );             break ;
       case 10020 : return ( "TRADE_RETCODE_PRICE_CHANGED" );       break ;
       case 10021 : return ( "TRADE_RETCODE_PRICE_OFF" );           break ;
       case 10022 : return ( "TRADE_RETCODE_INVALID_EXPIRATION" );   break ;
       case 10023 : return ( "TRADE_RETCODE_ORDER_CHANGED" );       break ;
       case 10024 : return ( "TRADE_RETCODE_TOO_MANY_REQUESTS" );   break ;
       case 10025 : return ( "TRADE_RETCODE_NO_CHANGES" );           break ;
       case 10026 : return ( "TRADE_RETCODE_SERVER_DISABLES_AT" );   break ;
       case 10027 : return ( "TRADE_RETCODE_CLIENT_DISABLES_AT" );   break ;
       case 10028 : return ( "TRADE_RETCODE_LOCKED" );               break ;
       case 10029 : return ( "TRADE_RETCODE_FROZEN" );               break ;
       case 10030 : return ( "TRADE_RETCODE_INVALID_FILL" );         break ;
       case 10031 : return ( "TRADE_RETCODE_CONNECTION" );           break ;
       case 10032 : return ( "TRADE_RETCODE_ONLY_REAL" );           break ;
       case 10033 : return ( "TRADE_RETCODE_LIMIT_ORDERS" );         break ;
       case 10034 : return ( "TRADE_RETCODE_LIMIT_VOLUME" );         break ;
       case 10035 : return ( "TRADE_RETCODE_INVALID_ORDER" );       break ;
       case 10036 : return ( "TRADE_RETCODE_POSITION_CLOSED" );     break ;
       default :
         return ( "TRADE_RETCODE_UNKNOWN=" + IntegerToString (retcode));
         break ;
     }
//---
  }
//+------------------------------------------------------------------+



+ 주문을 보낸 후 출력 r request_id 추가 - 요청 식별자, 전송 시 단말에서 설정

   printf ( "Перед открытием. PositionsTotal: %d, OrdersTotal: %d" , PositionsTotal (), OrdersTotal ());
      Trade.Buy( 0.01 ); // Если нет позиции и ордера - открываем позицию.
       MqlTradeResult result;
      Trade.Result(result);
      PRINT(result.request_id);
      ...

실제로 얼마나 많은 주문이 그곳으로 보내졌는지

С чего начать при создании торгового робота для Московской биржи MOEX
С чего начать при создании торгового робота для Московской биржи MOEX
  • www.mql5.com
Многие трейдеры на Московской бирже хотели бы автоматизировать свои торговые алгоритмы, но не знают с чего начать. Язык MQL5 предлагает не только огромный набор торговых функций, но и готовые классы, которые максимально облегчают первые шаги в алготрейдинге.
 

IMHO, OnTradeTransaction()도 아무 것도 보장하지 않으며 이벤트 순서도 보장하지 않으며 터미널 자체에 정보 전달도 보장하지 않습니다. 가장 안정적인 인터넷 제공 업체가 아닌 경우에 대해 이야기하고 있습니다.

OnTradeTransaction() 제어 메커니즘이 없거나 엄격한 순서로 모든 이벤트를 수신했거나 수신하지 않았습니다.


추신: 언어의 간결성에 대해..... 가장 바쁜 MQ 프로그래머가 아닌 일부는 오류 코드의 텍스트 설명을 반환하는 함수를 작성하는 데 2시간의 시간을 찾았을 것입니다. MQL5에서는 덜 썼을 것이고 MT4에서는 손으로 쓸 필요가 없었을 것입니다.

;)

 

코드베이스에서 발견하고 최신 코드를 추가했습니다.

 //+------------------------------------------------------------------+
//| Возврат стрингового результата торговой операции по его коду     |
//+------------------------------------------------------------------+
string ResultRetcodeDescription( int retcode)
  {
   string str;
//----
   switch (retcode)
     {
       case TRADE_RETCODE_REQUOTE :
         str= "TRADE_RETCODE_REQUOTE(Реквота)" ;
         break ;
       case TRADE_RETCODE_REJECT :
         str= "TRADE_RETCODE_REJECT(Запрос отвергнут)" ;
         break ;
       case TRADE_RETCODE_CANCEL :
         str= "TRADE_RETCODE_CANCEL(Запрос отменен трейдером)" ;
         break ;
       case TRADE_RETCODE_PLACED :
         str= "TRADE_RETCODE_PLACED(Ордер размещен)" ;
         break ;
       case TRADE_RETCODE_DONE :
         str= "TRADE_RETCODE_DONE(Заявка выполнена)" ;
         break ;
       case TRADE_RETCODE_DONE_PARTIAL :
         str= "TRADE_RETCODE_DONE_PARTIAL(Заявка выполнена частично)" ;
         break ;
       case TRADE_RETCODE_ERROR :
         str= "TRADE_RETCODE_ERROR(Ошибка обработки запроса)" ;
         break ;
       case TRADE_RETCODE_TIMEOUT :
         str= "TRADE_RETCODE_TIMEOUT(Запрос отменен по истечению времени)" ;
         break ;
       case TRADE_RETCODE_INVALID :
         str= "TRADE_RETCODE_INVALID(Неправильный запрос)" ;
         break ;
       case TRADE_RETCODE_INVALID_VOLUME :
         str= "Неправильный объем в запросе" ;
         break ;
       case TRADE_RETCODE_INVALID_PRICE :
         str= "TRADE_RETCODE_INVALID_VOLUME(Неправильная цена в запросе)" ;
         break ;
       case TRADE_RETCODE_INVALID_STOPS :
         str= "TRADE_RETCODE_INVALID_STOPS(Неправильные стопы в запросе)" ;
         break ;
       case TRADE_RETCODE_TRADE_DISABLED :
         str= "TRADE_RETCODE_TRADE_DISABLED(Торговля запрещена)" ;
         break ;
       case TRADE_RETCODE_MARKET_CLOSED :
         str= "TRADE_RETCODE_MARKET_CLOSED(Рынок закрыт)" ;
         break ;
       case TRADE_RETCODE_NO_MONEY :
         str= "TRADE_RETCODE_NO_MONEY(Нет достаточных денежных средств для выполнения запроса)" ;
         break ;
       case TRADE_RETCODE_PRICE_CHANGED :
         str= "TRADE_RETCODE_PRICE_CHANGED(Цены изменились)" ;
         break ;
       case TRADE_RETCODE_PRICE_OFF :
         str= "TRADE_RETCODE_PRICE_OFF(Отсутствуют котировки для обработки запроса)" ;
         break ;
       case TRADE_RETCODE_INVALID_EXPIRATION :
         str= "TRADE_RETCODE_INVALID_EXPIRATION(Неверная дата истечения ордера в запросе)" ;
         break ;
       case TRADE_RETCODE_ORDER_CHANGED :
         str= "TRADE_RETCODE_ORDER_CHANGED(Состояние ордера изменилось)" ;
         break ;
       case TRADE_RETCODE_TOO_MANY_REQUESTS :
         str= "TRADE_RETCODE_TOO_MANY_REQUESTS(Слишком частые запросы)" ;
         break ;
       case TRADE_RETCODE_NO_CHANGES :
         str= "TRADE_RETCODE_NO_CHANGES(В запросе нет изменений)" ;
         break ;
       case TRADE_RETCODE_SERVER_DISABLES_AT :
         str= "TRADE_RETCODE_SERVER_DISABLES_AT(Автотрейдинг запрещен сервером)" ;
         break ;
       case TRADE_RETCODE_CLIENT_DISABLES_AT :
         str= "TRADE_RETCODE_CLIENT_DISABLES_AT(Автотрейдинг запрещен клиентским терминалом)" ;
         break ;
       case TRADE_RETCODE_LOCKED :
         str= "TRADE_RETCODE_LOCKED(Запрос заблокирован для обработки)" ;
         break ;
       case TRADE_RETCODE_FROZEN :
         str= "TRADE_RETCODE_FROZEN(Ордер или позиция заморожены)" ;
         break ;
       case TRADE_RETCODE_INVALID_FILL :
         str= "TRADE_RETCODE_INVALID_FILL(Указан неподдерживаемый тип исполнения ордера по остатку)" ;
         break ;
       case TRADE_RETCODE_CONNECTION :
         str= "TRADE_RETCODE_CONNECTION(Нет соединения с торговым сервером)" ;
         break ;
       case TRADE_RETCODE_ONLY_REAL :
         str= "TRADE_RETCODE_ONLY_REAL(Операция разрешена только для реальных счетов)" ;
         break ;
       case TRADE_RETCODE_LIMIT_ORDERS :
         str= "TRADE_RETCODE_LIMIT_ORDERS(Достигнут лимит на количество отложенных ордеров)" ;
         break ;
       case TRADE_RETCODE_LIMIT_VOLUME :
         str= "TRADE_RETCODE_LIMIT_VOLUME(Достигнут лимит на объем ордеров и позиций для данного символа)" ;
         break ;
       case TRADE_RETCODE_INVALID_ORDER :
         str= "TRADE_RETCODE_INVALID_ORDER:Неверный или запрещённый тип ордера)" ;
         break ;
       case TRADE_RETCODE_POSITION_CLOSED :
         str= "TRADE_RETCODE_POSITION_CLOSED:Позиция с указанным POSITION_IDENTIFIER уже закрыта)" ;
         break ;
       case TRADE_RETCODE_INVALID_CLOSE_VOLUME :
         str= "TRADE_RETCODE_INVALID_CLOSE_VOLUME(Закрываемый объем превышает текущий объем позиции)" ;
         break ;
       case TRADE_RETCODE_CLOSE_ORDER_EXIST :
         str= "TRADE_RETCODE_CLOSE_ORDER_EXIST(Для указанной позиции уже есть ордер на закрытие)" ;
         break ;
       case TRADE_RETCODE_LIMIT_POSITIONS :
         str= "TRADE_RETCODE_LIMIT_POSITIONS(Количество открытых позиций, которое можно одновременно иметь на счете, может быть ограничено настройками сервера)" ;
         break ;
       case TRADE_RETCODE_REJECT_CANCEL :
         str= "TRADE_RETCODE_REJECT_CANCEL(Запрос на активацию отложенного ордера отклонен, а сам ордер отменен)" ;
         break ;
       case TRADE_RETCODE_LONG_ONLY :
         str= "TRADE_RETCODE_LONG_ONLY(Запрос отклонен, так как на символе установлено правило \"Разрешены только длинные позиции\")" ;
         break ;
       case TRADE_RETCODE_SHORT_ONLY :
         str= "TRADE_RETCODE_SHORT_ONLY(Запрос отклонен, так как на символе установлено правило \"Разрешены только короткие позиции\")" ;
         break ;
       case TRADE_RETCODE_CLOSE_ONLY :
         str= "TRADE_RETCODE_CLOSE_ONLY(Запрос отклонен, так как на символе установлено правило \"Разрешено только закрывать существующие позиции\")" ;
         break ;
       case TRADE_RETCODE_FIFO_CLOSE :
         str= "TRADE_RETCODE_FIFO_CLOSE(Запрос отклонен, так как для торгового счета установлено правило \"Разрешено закрывать существующие позиции только по правилу FIFO\")" ;
         break ;
       case TRADE_RETCODE_HEDGE_PROHIBITED:
         str= "TRADE_RETCODE_HEDGE_PROHIBITED(Запрос отклонен, так как для торгового счета установлено правило \"Запрещено открывать встречные позиции по одному символу\")" ;
         break ;
       //case : str=""; break;
       //case : str=""; break;
       //case : str=""; break;
       //case : str=""; break;
       default :
         str= "Неизвестный результат" ;
     }
//----
   return (str);
  }
 
Artyom Trishkin :

글쎄, 사람들은 블랙 박스에 대한 액세스 권한을 요청했습니다. 그들은 주어졌습니다.
이제 이 동기화를 직접 수행해야 합니다. 물어봤어? 그들이 물었다. 달리? 달리. 좋은데? 그들은 그것이 좋을 것이라고 말했다. 그들이 그것을 주었을 때, 그것은 나빠졌습니다.

1. 나는 묻지 않았다

2. 누구도 이에 대한 대가가 훨씬 더 중요한 데이터 무결성이 될 것이라고 말하지 않았습니다.

"자책"과 같은 적나라한 선동 대신 목발 없이 해결책을 제시할 수 있을까요?

 
Rashid Umarov :

코드베이스에서 발견하고 최신 코드를 추가했습니다.

ME 도움말에서 30분 만에 동일한 코드를 실행했습니다. 오류 코드 를 열고 마우스를 선택하고 Ctrl + C 빈 Excel 페이지를 만들고 Ctrl + V 대소문자가 포함된 열을 추가했습니다.

그 다음에   ME에서 Ctrl+C + Ctrl+V

그래, 분명히 "고난과 고난을 견디다"는 국군헌장 조항일 뿐만 아니라 우리의 마음가짐이다.

 
Andrei Trukhanovich :

1. 묻지 않았다

2. 누구도 이에 대한 대가가 훨씬 더 중요한 데이터 무결성이 될 것이라고 말하지 않았습니다.

"자책"과 같은 적나라한 선동 대신 목발 없이 해결책을 제시할 수 있을까요?

나는 아마 제안할 것이다. 하지만 훨씬 나중에. 주관적인 이유로. 안타깝게도. 그 동안 선동가를 고려할 수 있습니다. 금지되지 않습니다.
 
Igor Makanu :

ME 도움말에서 30분 만에 동일한 코드를 실행했습니다. 오류 코드 를 열고 마우스를 선택하고 Ctrl + C 빈 Excel 페이지를 만들고 Ctrl + V 대소문자가 포함된 열을 추가했습니다.

그 다음에   ME에서 Ctrl+C + Ctrl+V

그래, 분명히 "고난과 고난을 견디다"는 국군헌장 조항일 뿐만 아니라 우리의 마음가짐이다.

러시아어로? 스페인어? 영어로? 에 무슨?