FORTS: Um Anfängern zu helfen

 

Guten Tag!

Hier poste ich Empfehlungen, Bugs, Features und häufig genutzte Funktionen zum FORTS Terminmarkt

WICHTIG: Um das Thema nicht zu "dehnen", falls es Kommentare gibt,

oder Fragen haben - erstellen Sie ein separates Thema in diesem Abschnitt (ich werde hier nicht antworten).

Empfehlung :

Die MQL5- Standardbibliothek ist für den FOREX-Markt „geschärft“, also z

Entwicklungen von Experten für FORTS Ich empfehle, alles selbst zu schreiben.

Häufig verwendete und nützliche Funktionen:

Die Funktion zur Überprüfung der Handelsparameter des Servers des Maklers.

In dieser Funktion ist es notwendig, die Parameter zu überprüfen, die

Sie werden in Ihrem Berater verwenden. Hier ist ein Beispiel:

(NUR in OnInit() verwenden)

 //+------------------------------------------------------------------+
//| Expert Check Market Parameters function                          |
//+------------------------------------------------------------------+
bool CheckMarketParam( const string a_symbol )
{
//--- Check for full mode
   ENUM_SYMBOL_TRADE_MODE trade_mode = ENUM_SYMBOL_TRADE_MODE ( SymbolInfoInteger ( a_symbol, SYMBOL_TRADE_MODE ) );
  
   if ( trade_mode != SYMBOL_TRADE_MODE_FULL )
  {
     MessageBox ( "Символ " + a_symbol + " не поддерживает полную торговлю!" , "Ошибка" , MB_OK | MB_ICONHAND );
     return ( false );
  }
//--- Check trade execution mode
   ENUM_SYMBOL_TRADE_EXECUTION market_info = ENUM_SYMBOL_TRADE_EXECUTION ( SymbolInfoInteger ( a_symbol, SYMBOL_TRADE_EXEMODE ) );
    
   if ( market_info != SYMBOL_TRADE_EXECUTION_EXCHANGE )
  {
     MessageBox ( "Символ " + a_symbol + " не поддерживает TRADE EXECUTION EXCHANGE режим!" , "Ошибка" , MB_OK | MB_ICONHAND );
     return ( false );
  }
//--- Check orders mode
   int order_mode = int ( SymbolInfoInteger ( a_symbol, SYMBOL_ORDER_MODE ) );
  
   if ( ( SYMBOL_ORDER_MARKET & order_mode )!= SYMBOL_ORDER_MARKET )
  {
     MessageBox ( "Символ " + a_symbol + " не поддерживает Market Execution режим установки ордеров!" , "Ошибка" , MB_OK | MB_ICONHAND );
     return ( false );
  }
  
   if ( ( SYMBOL_ORDER_LIMIT & order_mode )!= SYMBOL_ORDER_LIMIT )
  {
     MessageBox ( "Символ " + a_symbol + " не поддерживает Limit режим установки ордеров!" , "Ошибка" , MB_OK | MB_ICONHAND );
     return ( false );
  }
  
   if ( ( SYMBOL_ORDER_STOP_LIMIT & order_mode ) != SYMBOL_ORDER_STOP_LIMIT )
  {
     MessageBox ( "Символ " + a_symbol + " не поддерживает Stop Limit режим установки ордеров!" , "Ошибка" , MB_OK | MB_ICONHAND );
     return ( false );
  }
  
   if ( ( SYMBOL_ORDER_STOP & order_mode )!= SYMBOL_ORDER_STOP )
  {
     MessageBox ( "Символ " + a_symbol + " не поддерживает Stop режим установки ордеров!" , "Ошибка" , MB_OK | MB_ICONHAND );
     return ( false );
  }
  
   if ( ( SYMBOL_ORDER_SL & order_mode) != SYMBOL_ORDER_SL )
  {
     MessageBox ( "Символ " + a_symbol + " не поддерживает Stop Loss режим установки ордеров!" , "Ошибка" , MB_OK | MB_ICONHAND );
     return ( false );
  }
  
   if ( ( SYMBOL_ORDER_TP & order_mode) != SYMBOL_ORDER_TP )
  {
     MessageBox ( "Символ " + a_symbol + " не поддерживает Take Profit режим установки ордеров!" , "Ошибка" , MB_OK | MB_ICONHAND );
     return ( false );
  }
//---Filing mode
   int filling_mode = int ( SymbolInfoInteger ( a_symbol, SYMBOL_FILLING_MODE ) );
  
   if ( ( SYMBOL_FILLING_IOC & filling_mode ) != SYMBOL_FILLING_IOC )
  {
     MessageBox ( "Символ " + a_symbol + " не поддерживает filling IOC режим исполнения ордеров!" , "Ошибка" , MB_OK | MB_ICONHAND );
     return ( false );
  }
  
   if ( ( SYMBOL_FILLING_FOK & filling_mode ) != SYMBOL_FILLING_FOK )
  {
     MessageBox ( "Символ " + a_symbol + " не поддерживает filling FOK режим исполнения ордеров!" , "Ошибка" , MB_OK | MB_ICONHAND );
     return ( false );
  }      
//---Ckeck expiration
   int symbol_exp_type = int ( SymbolInfoInteger ( a_symbol, SYMBOL_EXPIRATION_MODE ) );
//---  
   if ( ( symbol_exp_type & SYMBOL_EXPIRATION_DAY ) != SYMBOL_EXPIRATION_DAY )
  {
     MessageBox ( "Символ " + a_symbol + " не поддерживает экспирацию DAY!" , "Ошибка" , MB_OK | MB_ICONHAND );
     return ( false );
  }
   if ( ( symbol_exp_type & SYMBOL_EXPIRATION_SPECIFIED_DAY ) != SYMBOL_EXPIRATION_SPECIFIED_DAY )
  {
     MessageBox ( "Символ " + a_symbol + " не поддерживает экспирацию SPECIFIED DAY!" , "Ошибка" , MB_OK | MB_ICONHAND );
     return ( false );
  }
   return ( true );
} 

Anwendungsbeispiel:

 int OnInit ()
{
   if ( !CheckMarketParam( _Symbol ) ) return ( INIT_FAILED );
   return ( INIT_SUCCEEDED );
}

Abrufen der verbleibenden Tage bis zum Ablauf des Instruments:

 #define YEAR           365

int GetExpiration( const string aSymbol )
{
   MqlDateTime ExpData, CurData;
    
   datetime exp_time = datetime ( SymbolInfoInteger ( aSymbol, SYMBOL_EXPIRATION_TIME ) );
      
   TimeToStruct ( exp_time, ExpData );
   TimeTradeServer ( CurData );
      
   if ( ExpData.year != CurData.year )
  {
     return ( YEAR * ( ExpData.year - CurData.year ) - CurData.day_of_year + ExpData.day_of_year );
  }
   else
  {
     return ( ExpData.day_of_year - CurData.day_of_year );
  }
}

Abrufen des "Netto"-Positionspreises ohne Clearing:

 //+------------------------------------------------------------------+
//| Expert Get position price function                               |
//+------------------------------------------------------------------+
double GetPositionPrice( const string aSymbol )
{
   double price_in = 0 ;
   double volume_in = 0 ;
   double price_out = 0 ;
   double volume_out = 0 ;
   double price = 0 ;
   double volume = 0 ;
  
   if ( PositionSelect ( aSymbol ) )
  {
     ulong pos_id = ulong ( PositionGetInteger ( POSITION_IDENTIFIER ) );
    
     if ( pos_id > 0 )
    {
       if ( HistorySelectByPosition ( pos_id ) )
      {
         int deals = HistoryDealsTotal ();
      
         for ( int i = 0 ; i < deals; i++ )
        {
           ulong deal_ticket = HistoryDealGetTicket ( i );
           ulong order_ticket = ulong ( HistoryDealGetInteger ( deal_ticket, DEAL_ORDER ) );
        
           if ( order_ticket > 0 )
          {
             ENUM_DEAL_ENTRY deal_entry = ENUM_DEAL_ENTRY ( HistoryDealGetInteger ( deal_ticket, DEAL_ENTRY ) );
              
             if ( deal_entry == DEAL_ENTRY_IN )
            {
              price = HistoryDealGetDouble ( deal_ticket, DEAL_PRICE );
              volume = HistoryDealGetDouble ( deal_ticket, DEAL_VOLUME );
                                
              price_in += price * volume;
              volume_in += volume;  
            }
             else
             if ( deal_entry == DEAL_ENTRY_OUT )
            {
              price = HistoryDealGetDouble ( deal_ticket, DEAL_PRICE );
              volume = HistoryDealGetDouble ( deal_ticket, DEAL_VOLUME );
                                
              price_out += price * volume;
              volume_out += volume;  
            }
          }
        }
         if ( volume_out > 0 )
        {
           if ( volume_in > 0 ) { price_in = price_in / volume_in; } else return ( 0 );
          price_out = price_out / volume_out;
          price = ( price_in - price_out ) * ( volume_in - volume_out );
        }
         else
        {
           if ( volume_in > 0 ) { price = price_in / volume_in; } else return ( 0 );
        }
         return ( NormalizeDouble ( price, _Digits ) );
      }
       else
      {
         Print ( "GetPositionPrice: Невозможно получить историю позиции по символу " , aSymbol );
      }
    }
     else
    {
       Print ( "GetPositionPrice: Невозможно определить идентификатор позиции по символу " , aSymbol );
    }
  }
   return ( 0 );
} 

Erstellen einer globalen Terminalvariablen zum Zählen von Transaktionen:

(NUR in OnInit() verwenden)

   if ( ! GlobalVariableCheck ( "trans_count" ) )
  {
     datetime a_time = GlobalVariableSet ( "trans_count" , 0 );
    
     if ( ulong ( a_time ) == 0 )
    {
       MessageBox ( "Глобальная переменная терминала 'Счётчик транзакций' не создана!" , "Ошибка" , MB_OK | MB_ICONHAND );
       return ( INIT_FAILED );
    }
  }

Geschütztes Schreiben auf die globale Variable des Terminals (Transaktionszähler):

 //+------------------------------------------------------------------+
//| Expert Set transaction count function                            |
//+------------------------------------------------------------------+
void SetTransCount( const bool up_down )
{
   double tr_count;
   uint i = 0 ;
   do
  {
    i++;
     if ( GlobalVariableGet ( "trans_count" , tr_count ) )
    {
       if ( up_down )
      {
         if ( GlobalVariableSetOnCondition ( "trans_count" , tr_count + 1 , tr_count ) )
        {
          i = 100 ;
        }
      }
       else
      {
         if ( GlobalVariableSetOnCondition ( "trans_count" , tr_count - 1 , tr_count ) )
        {
          i = 100 ;
        }
      }
    }
  }  
   while ( i < 100 );
}

Wenn der Parameter up_down = true ist, dann erhöhen wir die globale Variable des Terminals,

umgekehrt.

Kassenprüfung mit automatischer Reduzierung des Volumens bei Geldmangel:

 //| Expert Check money function                                      |
//+------------------------------------------------------------------+ 
bool CheckMoney( long &volume )
{
   if ( volume <= 0 ) return ( false );
//---
   double symbol_go = SymbolInfoDouble ( _Symbol , SYMBOL_MARGIN_INITIAL );
   double free_margin = ( AccountInfoDouble ( ACCOUNT_FREEMARGIN ) / 100 ) * 90 ; //90% от свободных средств
   double real_go = NormalizeDouble ( symbol_go * volume, 2 );
//---     
   if ( real_go <= free_margin )
  {
     return ( true );
  }
   else
  {
     while ( real_go > free_margin )
    {
      volume--;
      
       if ( volume <= 0 )
      {
         Print ( "CheckMoney: Не хватает средств!" );
         return ( false );
      }  
      real_go = NormalizeDouble ( symbol_go * volume, 2 );
    }
     return ( true );
  }
   Print ( "CheckMoney: Не хватает средств!" ); 
   return ( false );
}

Platzieren einer Markt-/Limit-Order mit dem Befehl OrderSend()

if price = ''0" - Market Order:

 //+------------------------------------------------------------------+
//| Expert set order function                                        |
//+------------------------------------------------------------------+
void SetOrder( const string aSymbol, ulong &ticket, const double price, const double volume, const bool buy_sell )
{
   MqlTradeRequest request = { 0 };
   MqlTradeResult   result  = { 0 };
  ticket = 0 ;
   
//--- Fill structure
  request.magic = 1234567890 ;
  request.symbol = aSymbol;
  request.volume = volume; 
  request.type_filling = ORDER_FILLING_IOC ;
  request.type_time = ORDER_TIME_DAY ;
    
   if ( price == 0 )
  {
    request.action = TRADE_ACTION_DEAL ;
    request.comment = "Рыночный ордер..." ;
//---    
     if ( buy_sell )
    {
      request.type = ORDER_TYPE_BUY ;
    }
     else
    {
      request.type = ORDER_TYPE_SELL ;
    }
  }
   else
  { 
    request.action = TRADE_ACTION_PENDING ;
    request.price = price;
    request.comment = "Лимитный ордер..." ;
//---    
     if (buy_sell)
    {
      request.type = ORDER_TYPE_BUY_LIMIT ;
    }
     else
    {
      request.type = ORDER_TYPE_SELL_LIMIT ;
    }   
  }  
//--- Send order
   if ( OrderSend ( request, result ) )
  {
     if ( result.retcode == TRADE_RETCODE_PLACED ) 
    {
      ticket = result.order;
    }
     else
    {
       Print ( "SeOrder: Установка ордера не выполнена! " , aSymbol );
    }
  }
   else
  {
     Print ( "SeOrder: Ордер не отправлен! " , aSymbol );
  }
}

Löschen einer Order mit dem Befehl OrderSend()

 void RemoveOrder( ulong & ord_ticket )
{
   if ( ord_ticket >   0 )
  {
     if ( OrderSelect ( ord_ticket ) )
    {
       MqlTradeRequest request = { 0 };
       MqlTradeResult   result  = { 0 };
//---  
      request.action = TRADE_ACTION_REMOVE ;
      request.order  = ord_ticket;
//---  
       if ( OrderSend ( request, result ) )
      {
         if ( result.retcode == TRADE_RETCODE_PLACED )
        { 
          ord_ticket = result.order;
        }
         else
        {
           Print ( "RemoveOrder: Удаление старого ордера не выполнено! Билет = " , ord_ticket );
        }  
      }
       else
      {
         Print ( "RemoveOrder: Ордер не отослан! Билет = " , ord_ticket );
      }
    }
  }
}

Platzieren einer ausstehenden Bestellung mit dem Befehl OrderSend()

 //+------------------------------------------------------------------+
//| Place order                                                      |
//+------------------------------------------------------------------+
void PlaceOrder( const string aSymbol, ulong & ticket, const double price, const double volume, const bool buy_sell )
{
   MqlTradeRequest request = { 0 };
   MqlTradeResult   result  = { 0 };
  ticket = 0 ;
     
//--- Fill structure
  request.action = TRADE_ACTION_PENDING ;
  request.magic  = 1234567890 ;
  request.symbol = aSymbol;
  request.volume = volume;
  request.price  = price;
    
   if ( buy_sell )
  {
    request.type = ORDER_TYPE_BUY_LIMIT ;
  }
   else
  {
    request.type = ORDER_TYPE_SELL_LIMIT ;
  } 
  request.comment = "Отложенный ордер..." ;      
  request.type_filling = ORDER_FILLING_RETURN ;
  request.type_time = ORDER_TIME_DAY ;
  
//--- Send order
   if ( OrderSend ( request, result ) )
  {
     if ( result.retcode == TRADE_RETCODE_PLACED ) 
    {
      ticket = result.order;
    }
     else
    {
       Print ( "PlaceOrder: Ордер не установлен!" );
    }
  }
   else
  {
     Print ( "PlaceOrder: Ордер не отослан! " );
  }
}

Ändern einer ausstehenden Bestellung mit dem Befehl OrderSend()

 //+------------------------------------------------------------------+
// Modify order                                                      |
//+------------------------------------------------------------------+
void ModifyOrder( const string aSymbol, const double price, ulong & ticket )
{
   if ( ticket > 0 )
  {
     if ( OrderSelect ( ticket ) )
    {
       MqlTradeRequest request = { 0 };
       MqlTradeResult   result  = { 0 };
   
      request.action = TRADE_ACTION_MODIFY ;
      request.symbol = aSymbol;
      request.order  = ticket;
      request.price  = price;
      request.type_time = ORDER_TIME_DAY ;
  
       if ( OrderSend ( request, result ) )
      {
         if ( result.retcode == TRADE_RETCODE_PLACED ) 
        {
          ticket = result.order;
        }
         else
        {
           Print ( "ModifyOrder: Ордер не модифицирован! Билет = " , ticket );
        }
      }
       else
      {
         Print ( "ModifyOrder: Ордер не отослан! Билет " , ticket );
      }
    }
  }
}

Festlegen einer ausstehenden Bestellung mit dem Befehl OrderSendAsync()

Bei Verwendung dieses Befehls wird das Ticket dadurch nicht erhalten

Funktionen, sondern in der Funktion OnTradeTransaction(). In der Funktion OrderSendAsync() haben wir

Holen Sie sich die Nummer der Anfrage, um eine Bestellung aufzugeben:

uint req_id;
 ulong order_ticket = 0;
 void PlaceAsync( const string a_symbol, uint & req_id, const double price, const double volume, const bool buy_sell )
{
   MqlTradeRequest request = { 0 };
   MqlTradeResult   result  = { 0 };
  req_id = 0 ;
     
//--- Fill structure
  request.action = TRADE_ACTION_PENDING ;
  request.magic  = 1234567890 ;
  request.symbol = a_symbol;
  request.volume = volume;
  request.price  = price;
    
   if ( buy_sell )
  {
    request.type = ORDER_TYPE_BUY_LIMIT ;
  }
   else
  {
    request.type = ORDER_TYPE_SELL_LIMIT ;
  } 
  request.comment = "Отложенный ордер..." ;      
  request.type_filling = ORDER_FILLING_RETURN ;
  request.type_time = ORDER_TIME_DAY ;
  
//--- Send order
   if ( OrderSendAsync ( request, result ) )
  {
     if ( result.retcode == TRADE_RETCODE_PLACED ) 
    {
      req_id = result.request_id;
    }
     else
    {
       Print ( "PlaceAsync: Ордер не установлен! " , a_symbol );
    }
  }
   else
  {
     Print ( "PlaceAsync: Ордер на отослан! " , a_symbol );
  }
}

Ein Ticket per Anfragenummer erhalten:

 void OnTradeTransaction ( const MqlTradeTransaction &trans,
                         const MqlTradeRequest &request,
                         const MqlTradeResult &result )
{
   switch ( trans.type )
  {
     case TRADE_TRANSACTION_REQUEST : if ( trans.order_state == ORDER_STATE_STARTED )
                                    {
                                       if ( ( req_id != 0 ) && ( result.request_id == req_id ) )
                                      {
                                         if ( result.retcode == TRADE_RETCODE_PLACED )
                                        {
                                           if ( result.order > 0 )
                                          {
                                            order_ticket = result.order;
                                          }
                                           else
                                          {
                                             Print ( "OnTradeTransaction: Не получен билет! Запрос = " , req_id );
                                          }
                                        }
                                      }
                                    }  
                                     break ;
                                    
  }
}

Behandlung von Fehlern (Rückgabecodes) der Funktionen OrderSend() und OrderSendAsync()

Die Funktion CheckError() wird der Implementierung des Auftragsversands hinzugefügt Beispiel:

 void ModifyOrder( const string aSymbol, const double price, ulong & ticket )
{
   if ( ticket > 0 )
  {
     if ( OrderSelect ( ticket ) )
    {
       MqlTradeRequest request = { 0 };
       MqlTradeResult   result  = { 0 };
   
      request.action = TRADE_ACTION_MODIFY ;
      request.symbol = aSymbol;
      request.order  = ticket;
      request.price  = price;
      request.type_time = ORDER_TIME_DAY ;
  
       if ( OrderSend ( request, result ) )
      {
         if ( result.retcode == TRADE_RETCODE_PLACED ) 
        {
          ticket = result.order;
        }
         else
        {
          CheckError( result.retcode, "ModifyOrder: Ордер не модифицирован! Билет = " , ticket );
        }
      }
       else
      {
        CheckError( result.retcode, "ModifyOrder: Ордер не отослан! Билет " , ticket );
      }
    }
  }
}

Die Funktion CheckError() selbst ( nicht alle Rückgabecodes im Beispiel )

 void CheckError( const uint ret_code, const string err_msg, const ulong a_ticket )
{
   switch ( ret_code )
  {
     case TRADE_RETCODE_TRADE_DISABLED :
                                           break ;
     case TRADE_RETCODE_MARKET_CLOSED :
                                           break ;
     case TRADE_RETCODE_NO_MONEY :
                                           break ; 
     case TRADE_RETCODE_PRICE_OFF :
                                           break ;   
     case TRADE_RETCODE_TOO_MANY_REQUESTS :
                                           break ;
     case TRADE_RETCODE_SERVER_DISABLES_AT : 
                                           break ;
     case TRADE_RETCODE_CLIENT_DISABLES_AT : 
                                           break ;
     case TRADE_RETCODE_INVALID_PRICE :      
                                           break ;
     case TRADE_RETCODE_INVALID :
                                           break ;                                                       
                
     default : Print ( err_msg, GetRetCode( ret_code ), "; Билет = " , a_ticket );  
             break ;            
  }
}

Siehe Fortsetzung


Besonderheiten:

Beim Kauf von mehr als EINEM Kontrakt mit einer LIMIT-Order mit ORDER_FILLING_IOC-Ausführung,

eine Bestellung in der Historie kann als ORDER_STATE_CANCELED gespeichert werden, wenn die Bestellung mit dem ersten Band gefüllt ist,

und der zweite ist fehlgeschlagen.

Beispiel:

Kauf von 3 Kontrakten mit einer LIMIT-Order mit ORDER_FILLING_IOC-Ausführung,

es liegt folgende Situation vor:

1. Wenn wir alle drei Kontrakte gekauft haben, dann hat die Order in der Historie den Status = ORDER_STATE_FILLED

2. Wenn wir nichts gekauft haben, dann im Verlaufsstatus = ORDER_STATE_CANCELED

3. Wenn wir die ersten beiden Kontrakte (28449), aber keinen Kontrakt (28450) gekauft haben, dann ist der Status in der Historie = ORDER_STATE_CANCELED

4. Wenn wir die ersten beiden Kontrakte (28449) nicht gekauft haben, aber 1 (28450) gekauft haben, dann im Verlaufsstatus = ORDER_STATE_PARTIAL

======= Ende des Beispiels ===================

Die Anzahl ineffizienter Transaktionen (eine ineffiziente Transaktion ist eine Transaktion, die zu keiner Transaktion geführt hat.

Platzierung, Änderung und Löschung einer Order) am Terminmarkt FORTS ist auf 2000 pro vollständiger Handelssitzung begrenzt

von 19:00 Uhr des aktuellen Tages bis 18:45 Uhr des nächsten Tages. Für die Überschreitung - eine Geldstrafe der Börse

http://moex.com/n8725

Fehler:

1. Wenn auf dem MT5-Server des Brokers oder an der Börse ein Fehler auftritt, wird der Befehl

delete(modify) EXISTING order server gibt zurück:

Fehler 10013 = TRADE_RETCODE_INVALID = Ungültige Anfrage ( Ungültige Anfrage )

2. Manchmal, auch bei einem Fehlschlag, tritt beim Versuch, eine Pending- oder Limit-Order zu platzieren, ein Fehler auf – „ Das Instrument ist derzeit nicht verfügbar “.

(Das ist kein Tippfehler, das ist die Botschaft)

In der Dokumentation steht kein Rückgabecode für den Handelsserver!

 

Was ist also, wenn eine bestimmte Regelung nicht unterstützt wird? Warum sollte Ihnen das den Handel verbieten?

Vor allem, wenn "der Stop-Limit-Order-Einstellungsmodus nicht unterstützt wird"? Das ist das Problem, wenn man überhaupt nicht handeln kann.

© ZERSTÖRUNG IM KOPF

 

So steht es am Anfang geschrieben:

WICHTIG: Um das Thema nicht zu "strecken", sollten Sie Anmerkungen machen,

oder Fragen haben, erstellen Sieein separates Themain diesem Bereich(ich werde hier nicht antworten).

P / S für die besonders "Begabten":

In dieser Funktion müssen Sie die Parameter prüfen, die

die Sie in Ihrem EA verwenden werden. Hier ist ein Beispiel:

.......................

 

Fortsetzung folgt:

Häufig verwendete und nützliche Funktionen:

Die Funktion CheckError() selbst (nicht alle Rückgabewerte im Beispiel)

.........................................................................

Erläuterung der Rückgabecodes:

string GetRetCode( const uint code )
{
  string retcode;
  
  switch( code )
  {
    case TRADE_RETCODE_REQUOTE: retcode = "Реквота";
         break;
    case TRADE_RETCODE_REJECT: retcode = "Запрос отвергнут";
         break;
    case TRADE_RETCODE_CANCEL: retcode = "Запрос отменен трейдером";
         break;
    case TRADE_RETCODE_PLACED: retcode = "Ордер размещен";
         break;
    case TRADE_RETCODE_DONE: retcode = "Заявка выполнена";
         break;
    case TRADE_RETCODE_DONE_PARTIAL: retcode = "Заявка выполнена частично";
         break;
    case TRADE_RETCODE_ERROR: retcode = "Ошибка обработки запроса";
         break;
    case TRADE_RETCODE_TIMEOUT: retcode = "Запрос отменен по истечению времени";
         break;
    case TRADE_RETCODE_INVALID: retcode = "Неправильный запрос";
         break;
    case TRADE_RETCODE_INVALID_VOLUME: retcode = "Неправильный объем в запросе";
         break;
    case TRADE_RETCODE_INVALID_PRICE: retcode = "Неправильная цена в запросе";
         break;
    case TRADE_RETCODE_INVALID_STOPS: retcode = "Неправильные стопы в запросе";
         break;
    case TRADE_RETCODE_TRADE_DISABLED: retcode = "Торговля запрещена";
         break;
    case TRADE_RETCODE_MARKET_CLOSED: retcode = "Рынок закрыт";
         break;
    case TRADE_RETCODE_NO_MONEY: retcode = "Нет достаточных денежных средств для выполнения запроса";
         break;
    case TRADE_RETCODE_PRICE_CHANGED: retcode = "Цены изменились";
         break;
    case TRADE_RETCODE_PRICE_OFF: retcode = "Отсутствуют котировки для обработки запроса";
         break;
    case TRADE_RETCODE_INVALID_EXPIRATION: retcode = "Неверная дата истечения ордера в запросе";
         break;
    case TRADE_RETCODE_ORDER_CHANGED: retcode = "Состояние ордера изменилось";
         break;
    case TRADE_RETCODE_TOO_MANY_REQUESTS: retcode = "Слишком частые запросы";
         break;
    case TRADE_RETCODE_NO_CHANGES: retcode = "В запросе нет изменений";
         break;
    case TRADE_RETCODE_SERVER_DISABLES_AT: retcode = "Автотрейдинг запрещен сервером";
         break;
    case TRADE_RETCODE_CLIENT_DISABLES_AT: retcode = "Автотрейдинг запрещен клиентским терминалом";
         break;
    case TRADE_RETCODE_LOCKED: retcode = "Запрос заблокирован для обработки";
         break;
    case TRADE_RETCODE_FROZEN: retcode = "Ордер или позиция заморожены";
         break;
    case TRADE_RETCODE_INVALID_FILL: retcode = "Указан неподдерживаемый тип исполнения ордера по остатку";
         break;
    case TRADE_RETCODE_CONNECTION: retcode = "Нет соединения с торговым сервером";
         break;
    case TRADE_RETCODE_ONLY_REAL: retcode = "Операция разрешена только для реальных счетов";
         break;
    case TRADE_RETCODE_LIMIT_ORDERS: retcode = "Достигнут лимит на количество отложенных ордеров";
         break;
    case TRADE_RETCODE_LIMIT_VOLUME: retcode = "Достигнут лимит на объем ордеров и позиций для данного символа";
         break;
    case TRADE_RETCODE_INVALID_ORDER: retcode = "Неверный или запрещённый тип ордера";
         break;
    case TRADE_RETCODE_POSITION_CLOSED: retcode = "Позиция с указанным POSITION_IDENTIFIER уже закрыта";
         break;
    default: retcode = "Нет кода возврата.";  
         break; 
  }
  return( retcode );
}

Empfehlung:

Bei der Entwicklung von EAs für FORTS empfehle ich nicht die Verwendung des Tick-Ereignisses, sondern

ist es besser, das Ereignis BookEvent zu verwenden

Beispiele:

Hinzufügen eines Häkchens:

(NUR in OnInit() verwenden)

  if ( !MarketBookAdd( _Symbol ) )
  {
    MessageBox( "Не добавлен стакан фьючерса " + _Symbol + "!", "Ошибка", MB_OK | MB_ICONHAND );
    return( INIT_FAILED );
  } 

Entfernen eines Abonnements für ein Glas:

void OnDeinit( const int reason )
{
  MarketBookRelease( _Symbol );
}

Holen Sie sich die besten ASK und BID und deren Volumina aus dem Preisüberblick:

double sell_price, buy_price;
long sell_volume, buy_volume;

//+------------------------------------------------------------------+
//| Expert Get Stakan values function                                |
//+------------------------------------------------------------------+ 
bool GetStakanValues( const string aSymbol, double &sell_price,
                      double &buy_price, long &sell_volume, long &buy_volume )
{
  MqlBookInfo book_price[];
  buy_price  = 0;
  sell_price = DBL_MAX;
  buy_volume = 0;
  sell_volume = 0;
  
//--- Get stakan
  if ( MarketBookGet( aSymbol, book_price ) )//getBook )
  {
    int size = ArraySize( book_price );
//---    
    if ( size > 0 )
    {
      double a_min_price = SymbolInfoDouble( aSymbol, SYMBOL_SESSION_PRICE_LIMIT_MIN );
      double a_max_price = SymbolInfoDouble( aSymbol, SYMBOL_SESSION_PRICE_LIMIT_MAX );
//---     
      for( int i = 0; i < size; i++ )
      {
        if ( book_price[i].type == BOOK_TYPE_SELL )
        {
          if ( book_price[i].price < sell_price )
          {
            sell_price = book_price[i].price;
            sell_volume = book_price[i].volume;  
          }
        }
        else
        if ( book_price[i].type == BOOK_TYPE_BUY ) //First buy - exit
        {
          buy_price = book_price[i].price;
          buy_volume = book_price[i].volume;
          break;
        }
      }
      if ( ( buy_price <= a_max_price ) && ( buy_price >= a_min_price ) &&
           ( sell_price <= a_max_price ) && ( sell_price >= a_min_price ) )
      {
        if ( sell_price == DBL_MAX ) sell_price = 0;
//---        
        if ( ( sell_price > 0 ) && ( buy_price > 0 ) )
        {
          return( true );
        }  
      }
    }
  }
//---
  if ( sell_price == DBL_MAX ) sell_price = 0;
//---   
  return( false); 
}

Funktionsaufruf:

Die Prüfung, ob ( a_symbol == _Symbol ), ist ein MUSS, denn sie stellt sicher, dass sich Ihr Preisstapel geändert hat.

//+------------------------------------------------------------------+
//| Expert On Book event function                                    |
//+------------------------------------------------------------------+  
void OnBookEvent( const string &a_symbol )
{
  if ( a_symbol == _Symbol )
  {
    if ( GetStakanValues( _Symbol, sell_price, buy_price, sell_volume, buy_volume ) )
    {
      //you code
    }
  }
}
 

DANKESCHÖN!!!)

 

Besondere Merkmale:

Formeln für die Berechnung und Vergabe von Punkten für ineffiziente und fehlerhafte

Transaktionen in der Anlage.

P/S Sowohl Regeln als auch Punkte werden oft genug geändert :(

Dateien:
 

Häufig verwendete und nützliche Funktionen:

Die Funktion SetStDayTime() gibt die Startzeit des Handelstages (zum Zeitpunkt der Anfrage) zurück.

Die Funktion GetExgangeFee() gibt die Börsenprovision und die Anzahl der Transaktionen für den Handelstag (zum Zeitpunkt der Anfrage) zurück:

//+------------------------------------------------------------------+
//|                                                       Tr_fee.mq5 |
//|                                          Copyright 2015, Mikalas |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, Mikalas"
#property link      "https://www.mql5.com"
#property version   "1.00"
//
input long   TrPoint   = 1;              //Балл за транзакцию
input long   DealPoint = 40;             //Балл за сделку
//
datetime start_day_time;
//
//+------------------------------------------------------------------+
//| Expert Set start day time function                               |
//+------------------------------------------------------------------+
datetime SetStDayTime()
{
  MqlDateTime  dt_str; 
  TimeTradeServer( dt_str );
//---
  if ( ( dt_str.day_of_week == 0 ) || ( dt_str.day_of_week == 6 ) ) return( datetime( 0 ) );  
//---
  string time_str = IntegerToString( dt_str.year ) + "." + IntegerToString( dt_str.mon ) +
                    "." + IntegerToString( dt_str.day ) + " 19:00:00";
  ulong cur_day = ulong( StringToTime( time_str ) );                     

  if ( ( dt_str.hour >= 19 ) && ( dt_str.hour <= 23 ) )
  {
    return( StringToTime( time_str ) );
  }
  else
  {
    ulong one_day = 24 * 60 * 60;
//---      
    if ( dt_str.day_of_week == 1 )
    {
      cur_day -= one_day * 3;
    }
    else
    {
      cur_day -= one_day;
    }
    return( datetime( cur_day ) );
  }  
  return( datetime( 0 ) );
}
//+------------------------------------------------------------------+
//| Expert calc deals fee function                                   |
//+------------------------------------------------------------------+
double GetExgangeFee( const datetime start_time, long& deals )
{
  double all_fee = 0.0;
  ulong deal_ticket;
  deals = 0;
//---  
  if ( HistorySelect( start_time, TimeTradeServer() ) )
  {
    int deals_total = HistoryDealsTotal();
//---   
    if ( deals_total > 0 )
    {
      for ( uint i = 0; i < uint( deals_total ); i++ )
      {
        deal_ticket = HistoryDealGetTicket( i );
//---        
        if ( deal_ticket > 0 )
        {
          ulong order_ticket = ulong( HistoryDealGetInteger( deal_ticket, DEAL_ORDER ) );
          
          if ( order_ticket > 0 )
          {
            deals++;
            all_fee += HistoryDealGetDouble( deal_ticket, DEAL_COMMISSION );
          }  
        }
      }
      return( MathAbs( all_fee ) );
    }  
  }
  return( 0 );
}
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
  long a_deals;
  start_day_time = SetStDayTime();
//---  
  if ( ulong( start_day_time ) == 0 )
  {
    MessageBox( "Не установлено время начала торгового дня!", "Ошибка", MB_OK | MB_ICONHAND );
    return( INIT_FAILED );
  } 
  Print( "Exgange Fee = ", GetExgangeFee( start_day_time, a_deals ), "; Deals = ", a_deals );
  return( INIT_SUCCEEDED );
}
 
Михаил:

Häufig verwendete und nützliche Funktionen:

Die Funktion SetStDayTime() gibt die Startzeit des Handelstages (zum Zeitpunkt der Anfrage) zurück.

Die Funktion GetExgangeFee() gibt die Börsenprovision und die Anzahl der Transaktionen für den Handelstag (zum Zeitpunkt der Anfrage) zurück:

Dies ist ein noch nie dagewesener Anwärter auf den Titel "Hindu Coder - 2015".

SetStDayTime() wird mit zwei Zeilen gelöst. Aber das müssen Sie natürlich nicht...

 

Michael, ich danke Ihnen für Ihre Beiträge!

Die Erfindung einiger Fahrräder durch mich wird annulliert )

 
Михаил:

Ich muss es tun.

Und wie macht man das?

Sie müssen mit der numerischen Darstellung der Zeit arbeiten.

datetime a=TimeTradeServer(); 

Die Startzeit des Tages:

datetime r=(a/86400)*86400

Die Zeit um 19:00 Uhr heute:

datetime r=(a/86400)*86400+19*3600;

Wenn die Zeit um 19:00 Uhr heute größer ist als die aktuelle Zeit, dann brauchen wir die 19:00 Uhr von gestern:

if(r>a)r-=86400;

Wenn wir das Wochenende auslassen müssen, prüfen wir den Wochentag, wenn Sonntag, ziehen wir 86400*2 ab, wenn Samstag, ziehen wir 86400 ab (um Freitag zu erhalten).

Es geht ungefähr so.

Dann, für die Anzeige, falls erforderlich, in eine Zeichenkette konvertieren:

TimeToStr(r)
 
Михаил:

Und das hohe Jahr?

Übersetzen Sie nun Ihre Gedanken in konkreten Code.

Schreiben Sie meine Funktion auf Ihre Weise um, und wie Sie sagten, in ZWEI Zeilen!

Was ist mit dem Schaltjahr? Alles wird gut werden.

Machen Sie es einfach selbst, ich möchte Ihren Code nicht vollständig verstehen, falls ich etwas übersehen sollte, was für eine Freude Sie haben werden.

Grund der Beschwerde: