FORTS: 초보자를 돕기 위해 - 페이지 2

 
Михаил :

그렇다면 당신은 "Best Pupuas Encoder - 2015" 타이틀의 첫 번째 경쟁자입니다.

P/S 주제를 읽으시는 분들께 부탁드리며, 웃으면서 의자에서 떨어지지 마세요 :)

글쎄요, 화내세요, 4줄의 코드를 알아내지 못했다면 화내세요(특히 이해를 돕기 위해 2줄이 아닌 4줄)

어려움은 무엇입니까? 숫자 86400이 무엇인지 명확하지 않습니까? 아니면 3600?

86400은 하루의 초 수입니다. 3600 - 한 시간 안에.

추신. 그게 무슨 웃음이야? 여기서 당신은 울어야 합니다.

 

자주 사용하고 유용한 기능:  

SetStDayTime() 함수는 그다지 빠르지 않았기 때문에

수정된 것을 게시합니다(Sergey 덕분에).

 datetime SetStDayTime()
{
   MqlDateTime   dt_str;
   ulong one_day = 86400 ;
   TimeTradeServer ( dt_str );
   int hour = dt_str.hour;
  dt_str.hour = 19 ;
  dt_str.min = 0 ;
  dt_str.sec = 0 ;
   ulong time_start = ulong ( StructToTime ( dt_str ) );
//---   
   switch ( dt_str.day_of_week )
  {
     case 6 :  time_start -= one_day;
             break ;
     case 0 :  time_start -= one_day * 2 ;
             break ;
     case 1 :   if ( hour < 19 ) time_start -= one_day * 3 ;
             break ;
     default : if ( hour < 19 ) time_start -= one_day;
             break ;
  }
   return ( datetime ( time_start ) );
}
 

특징:

OrderSend() 함수의 반환 코드와 주문 티켓에서 확인(TRADE_RETCODE_PLACED)을 받은 후,

 if ( OrderSend ( request, result ) )
{
   if ( result.retcode == TRADE_RETCODE_PLACED )
  { 
    ticket = result.order;
  }
}

OnTradeTransaction() 의 OrderSendAsync() 함수 의 경우 이것이 다음을 의미하지는 않습니다.

주문은 실제로 교환에 배치됩니다.

따라서 주문 상태에 대한 추가 확인이 필요합니다(주문에 대한 다른 작업과 마찬가지로).

 enum ENUM_ORD_REAL_STATE
{
  ORD_NOT_SPECIFIED         = 0 , //Состояние ордера не определено
  ORD_NONE_CANCELED         = 1 , //Ордера нет, отменён пользователем
  ORD_NONE_PARTIAL_CANCELED = 2 , //Ордера нет, исполнился частично (не был залит вторым объёмом)
  ORD_NONE_PARTIAL          = 3 , //Ордера нет, исполнился частично
  ORD_NONE_EXPIRED          = 4 , //Ордера нет, удалён по сроку
  ORD_NONE_FILLED           = 5 , //Ордера нет, исполнился полностью
  ORD_NONE_REJECTED         = 6 , //Ордера нет, отклонён брокером(биржей)
  ORD_BUSY                  = 7 , //Ордер находится в переходном состоянии
  ORD_EXIST                 = 8 , //Ордер выставлен на биржу, возможны действия над ним
  ORD_EXIST_PARTIAL         = 9    //Ордер выставлен на биржу, частично исполнился, возможны действия над ним
};
//
ENUM_ORD_REAL_STATE CheckOrderState( const ulong ticket )
{
   if ( ticket > 0 )
  {
     if ( HistoryOrderSelect ( ticket ) ) //Только не существующий ордер может находится в истории
    {
       ENUM_ORDER_STATE ord_state = ENUM_ORDER_STATE ( HistoryOrderGetInteger ( ticket, ORDER_STATE ) );
       double init_volume = HistoryOrderGetDouble ( ticket, ORDER_VOLUME_INITIAL );
       double cur_volume = HistoryOrderGetDouble ( ticket, ORDER_VOLUME_CURRENT );
//---      
       switch ( ord_state )
      {
                                                           
         case ORDER_STATE_CANCELED :       if ( init_volume == init_volume )
                                         {
                                           return ( ORD_NONE_CANCELED );
                                         }
                                         else
                                         {
                                           return ( ORD_NONE_PARTIAL_CANCELED );
                                         }  
                                         break ;
                                         
         case ORDER_STATE_PARTIAL :         return ( ORD_NONE_PARTIAL );
                                         break ;
                                         
         case ORDER_STATE_EXPIRED :         return ( ORD_NONE_EXPIRED );
                                         break ;
                                                                              
         case ORDER_STATE_FILLED :         return ( ORD_NONE_FILLED );
                                         break ;
                                         
         case ORDER_STATE_REJECTED :       return ( ORD_NONE_REJECTED );
                                         break ;   
 
       
      }
    }
     else
     if ( OrderSelect ( ticket ) ) 
    {
       ENUM_ORDER_STATE ord_state = ENUM_ORDER_STATE ( OrderGetInteger ( ORDER_STATE ) );
//---      
       switch ( ord_state )
      {
         case ORDER_STATE_STARTED :
         case ORDER_STATE_REQUEST_ADD :
         case ORDER_STATE_REQUEST_MODIFY :
         case ORDER_STATE_REQUEST_CANCEL : return ( ORD_BUSY );
                                         break ; 
 
         case ORDER_STATE_PARTIAL :         return ( ORD_EXIST_PARTIAL );
                                         break ;
                                          
         case ORDER_STATE_PLACED :         return ( ORD_EXIST );
                                         break ;
      }
    }
  }
   return ( ORD_NOT_SPECIFIED );
}
 

CheckOrderState() 함수에 오타가 있습니다.

init_volume == init_volume 대신

init_volume == cur_volume 이어야 합니다.

 

자주 사용하고 유용한 기능:  

재설계된 CheckOrderState() 함수는 주문 데이터를 수신/수신하지 않는 기능과 함께 OrderRealSelect()로 알려졌습니다.

 #define ERR_ZERO_TICKET - 1
//
enum ENUM_ORD_REAL_STATE
{
  ORD_NOT_SPECIFIED         = 0 , //Состояние ордера не определено
  ORD_NONE_CANCELED         = 1 , //Ордера нет, отменён пользователем
  ORD_NONE_PARTIAL_CANCELED = 2 , //Ордера нет, исполнился частично (не был залит вторым объёмом)
  ORD_NONE_PARTIAL          = 3 , //Ордера нет, исполнился частично
  ORD_NONE_EXPIRED          = 4 , //Ордера нет, удалён по сроку
  ORD_NONE_FILLED           = 5 , //Ордера нет, исполнился полностью
  ORD_NONE_REJECTED         = 6 , //Ордера нет, отклонён брокером(биржей)
  ORD_BUSY                  = 7 , //Ордер находится в переходном состоянии
  ORD_EXIST                 = 8 , //Ордер выставлен на биржу, возможны действия над ним
  ORD_EXIST_PARTIAL         = 9    //Ордер выставлен на биржу, частично исполнился, возможны действия над ним
};
enum ENUM_ORD_SELECT
{
  SELECT_ERROR = 0 ,
  SELECT_FALSE = 1 ,
  SELECT_TRUE  = 2 ,
  SELECT_BUSY  = 3
};
//
struct ORDER_DATA
{
   int                      error_code;
   datetime                 time_setup;
   ENUM_ORDER_TYPE          type;
   ENUM_ORDER_STATE         state;
  ENUM_ORD_REAL_STATE     real_state;
   datetime                 expiration;
   datetime                 time_done;
   long                     t_set_msc;
   long                     t_done_msc; 
   ENUM_ORDER_TYPE_FILLING type_filling;
   ENUM_ORDER_TYPE_TIME     type_time;
   long                     magic;
   long                     pos_id;
   double                   vol_init;
   double                   vol_cur;
   double                   price_open;
   double                   sl;
   double                   tp;
   double                   price_cur;
   double                   price_stlim;
   string                   symbol;
   string                   comment;      
};
//
//+------------------------------------------------------------------+
// Expert Order Real Select function                                 |
//+------------------------------------------------------------------+
ENUM_ORD_SELECT OrderRealSelect( const ulong ticket, ORDER_DATA &ord_data, const bool get_data )
{
   double init_vol = 0 ;
   double cur_vol = 0 ;
   ZeroMemory ( ord_data );
  ord_data.real_state = ORD_NOT_SPECIFIED;
  ord_data.error_code = ERR_SUCCESS ;
   ResetLastError ();
//---  
   if ( ticket > 0 )
  {
     if ( HistoryOrderSelect ( ticket ) )
    {
       if ( get_data )
      {
        ord_data.comment = HistoryOrderGetString ( ticket, ORDER_COMMENT );
        ord_data.expiration = datetime ( HistoryOrderGetInteger ( ticket, ORDER_TIME_EXPIRATION ) ); 
        ord_data.magic = HistoryOrderGetInteger ( ticket, ORDER_MAGIC );
        ord_data.pos_id = HistoryOrderGetInteger ( ticket, ORDER_POSITION_ID );
        ord_data.price_cur = HistoryOrderGetDouble ( ticket, ORDER_PRICE_CURRENT );
        ord_data.price_open = HistoryOrderGetDouble ( ticket, ORDER_PRICE_OPEN );
        ord_data.price_stlim = HistoryOrderGetDouble ( ticket, ORDER_PRICE_STOPLIMIT );
        ord_data.sl = HistoryOrderGetDouble ( ticket, ORDER_SL );
        ord_data.state = ENUM_ORDER_STATE ( HistoryOrderGetInteger ( ticket, ORDER_STATE ) );
        ord_data.symbol = HistoryOrderGetString ( ticket, ORDER_SYMBOL );
        ord_data.t_done_msc = datetime ( HistoryOrderGetInteger ( ticket, ORDER_TIME_DONE_MSC ) );
        ord_data.t_set_msc = datetime ( HistoryOrderGetInteger ( ticket, ORDER_TIME_SETUP_MSC ) );
        ord_data.time_done = datetime ( HistoryOrderGetInteger ( ticket, ORDER_TIME_DONE ) );
        ord_data.time_setup = datetime ( HistoryOrderGetInteger ( ticket, ORDER_TIME_SETUP ) );
        ord_data.tp = HistoryOrderGetDouble ( ticket, ORDER_TP );
        ord_data.type = ENUM_ORDER_TYPE ( HistoryOrderGetInteger ( ticket, ORDER_TYPE ) );
        ord_data.type_filling = ENUM_ORDER_TYPE_FILLING ( HistoryOrderGetInteger ( ticket, ORDER_TYPE_FILLING ) );
        ord_data.type_time = ENUM_ORDER_TYPE_TIME ( HistoryOrderGetInteger ( ticket, ORDER_TYPE_TIME ) );
        ord_data.vol_cur = HistoryOrderGetDouble ( ticket, ORDER_VOLUME_CURRENT );
        ord_data.vol_init = HistoryOrderGetDouble ( ticket, ORDER_VOLUME_INITIAL );
      }
       else
      {
        ord_data.state = ENUM_ORDER_STATE ( HistoryOrderGetInteger ( ticket, ORDER_STATE ) );
        cur_vol = HistoryOrderGetDouble ( ticket, ORDER_VOLUME_CURRENT );
        init_vol = HistoryOrderGetDouble ( ticket, ORDER_VOLUME_INITIAL );
      }   
//---
       switch ( ord_data.state )
      { 
         case ORDER_STATE_CANCELED : if ( get_data )
                                   {
                                     if ( ord_data.vol_init == ord_data.vol_cur )
                                     {
                                       ord_data.real_state = ORD_NONE_CANCELED;
                                     }
                                     else
                                     {
                                       ord_data.real_state = ORD_NONE_PARTIAL_CANCELED;
                                     }
                                   }
                                   else
                                   {
                                     if ( init_vol == cur_vol )
                                     {
                                       ord_data.real_state = ORD_NONE_CANCELED;
                                     }
                                     else
                                     {
                                       ord_data.real_state = ORD_NONE_PARTIAL_CANCELED;
                                     }
                                   }    
                                   break ;
                                        
         case ORDER_STATE_PARTIAL :  ord_data.real_state = ORD_NONE_PARTIAL;
                                   break ;
                                         
         case ORDER_STATE_EXPIRED :  ord_data.real_state = ORD_NONE_EXPIRED;
                                   break ;
                                                                              
         case ORDER_STATE_FILLED :   ord_data.real_state = ORD_NONE_FILLED;
                                   break ;
                                         
         case ORDER_STATE_REJECTED : ord_data.real_state = ORD_NONE_REJECTED;
                                   break ;  
      }
    }
     else
     if ( OrderSelect ( ticket ) )
    {
       if ( get_data )
      {
        ord_data.comment = OrderGetString ( ORDER_COMMENT );
        ord_data.expiration = datetime ( OrderGetInteger ( ORDER_TIME_EXPIRATION ) ); 
        ord_data.magic = OrderGetInteger ( ORDER_MAGIC );
        ord_data.pos_id = OrderGetInteger ( ORDER_POSITION_ID );
        ord_data.price_cur = OrderGetDouble ( ORDER_PRICE_CURRENT );
        ord_data.price_open = OrderGetDouble ( ORDER_PRICE_OPEN );
        ord_data.price_stlim = OrderGetDouble ( ORDER_PRICE_STOPLIMIT );
        ord_data.sl = OrderGetDouble ( ORDER_SL );
        ord_data.state = ENUM_ORDER_STATE ( OrderGetInteger ( ORDER_STATE ) );
        ord_data.symbol = OrderGetString ( ORDER_SYMBOL );
        ord_data.t_done_msc = datetime ( OrderGetInteger ( ORDER_TIME_DONE_MSC ) );
        ord_data.t_set_msc = datetime ( OrderGetInteger ( ORDER_TIME_SETUP_MSC ) );
        ord_data.time_done = datetime ( OrderGetInteger ( ORDER_TIME_DONE ) );
        ord_data.time_setup = datetime ( OrderGetInteger ( ORDER_TIME_SETUP ) );
        ord_data.tp = OrderGetDouble ( ORDER_TP );
        ord_data.type = ENUM_ORDER_TYPE ( OrderGetInteger ( ORDER_TYPE ) );
        ord_data.type_filling = ENUM_ORDER_TYPE_FILLING ( OrderGetInteger ( ORDER_TYPE_FILLING ) );
        ord_data.type_time = ENUM_ORDER_TYPE_TIME ( OrderGetInteger ( ORDER_TYPE_TIME ) );
        ord_data.vol_cur = OrderGetDouble ( ORDER_VOLUME_CURRENT );
        ord_data.vol_init = OrderGetDouble ( ORDER_VOLUME_INITIAL );
      }
       else
      {
        ord_data.state = ENUM_ORDER_STATE ( OrderGetInteger ( ORDER_STATE ) );
      }
//--- 
       switch ( ord_data.state )
      { 
         case ORDER_STATE_STARTED :
         case ORDER_STATE_REQUEST_ADD :
         case ORDER_STATE_REQUEST_MODIFY :
         case ORDER_STATE_REQUEST_CANCEL : ord_data.real_state = ORD_BUSY;
                                         break ; 
 
         case ORDER_STATE_PARTIAL :        ord_data.real_state = ORD_EXIST_PARTIAL;
                                         break ;
                                          
         case ORDER_STATE_PLACED :         ord_data.real_state = ORD_EXIST;
                                         break ;
      }
    }
     else
    {
      ord_data.error_code = GetLastError ();
    }  
//---   
     if ( ( ord_data.error_code != ERR_SUCCESS ) ||
       ( ord_data.real_state == ORD_NOT_SPECIFIED ) )
    {
       return ( SELECT_ERROR );
    }
     else
    {
       switch ( ord_data.real_state )
      {
         case ORD_BUSY:           return ( SELECT_BUSY );
                                 break ;
                        
         case ORD_EXIST:   
         case ORD_EXIST_PARTIAL: return ( SELECT_TRUE );
                                 break ;
                              
         default :                 return ( SELECT_FALSE );
                                 break ;                                             
      }
    }
  } 
   else
  {
    ord_data.error_code = ERR_ZERO_TICKET; 
     return ( SELECT_ERROR );
  }
}


주문을 수정하거나 삭제하려면 주문이 존재한다는 사실만 알면 됩니다.

ORDER_DATA order_data;
   ulong a_ticket = 12345 ;
//---
   if ( OrderRealSelect( a_ticket, order_data, false ) == SELECT_TRUE )
  {
     //Удаляем или модифицируем ордер ( false - не получаем данные по ордеру)
  }

삭제 후 주문에 대한 데이터를 가져와야 하는 경우:

ORDER_DATA order_data;
   ulong a_ticket = 12345 ;
//---
   if ( OrderRealSelect( a_ticket, order_data, true ) == SELECT_FALSE )
  {
    a_ticket = 0 ;
     //Смотрим данные по ордеру в order_data    
  } 

오류의 경우:

ORDER_DATA order_data;
   ulong a_ticket = 12345 ;
//---
   if ( OrderRealSelect( a_ticket, order_data, true ) == SELECT_ERROR )
  {
     //Не важно, запрашивали мы данные по ордеру (true) или нет(false) коды ошибки 
     //будут всегда
     switch ( order_data.error_code )
    {
       //.................................
    }    
  } 
 

자주 사용하고 유용한 기능:  

비효율적인 거래를 계산하기 위해 재설계된 기능 세트:

 //+------------------------------------------------------------------+
//|                                                     Tr_count.mq5 |
//|                                          Copyright 2015, Mikalas |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, Mikalas"
#property link        "https://www.mql5.com"
#property version    "1.00"
//
input double   TrPoint   = 1 ;     //Балл за транзакцию
input ulong    DealPoint = 40 ;   //Балл за сделку
input double   NotEff    = 1970 ; //Неэффективных транзакций 
//
bool set_error;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit ()
{
  set_error = false ;
//---  
   if ( ! GlobalVariableCheck ( "trans_count" ) )
  {
     datetime a_time = GlobalVariableSet ( "trans_count" , 0 );
    
     if ( ulong ( a_time ) == 0 )
    {
       MessageBox ( "Глобальная переменная терминала 'Счётчик транзакций' не создана!" , "Ошибка" , MB_OK | MB_ICONHAND );
       return ( INIT_FAILED );
    }
  }
//---
   if ( ! GlobalVariableCheck ( "not_eff_cnt" ) )
  {
     datetime a_time = GlobalVariableSet ( "not_eff_cnt" , 0 );
    
     if ( ulong ( a_time ) == 0 )
    {
       MessageBox ( "Глобальная переменная терминала 'Счётчик неэффективных транзакций' не создана!" , "Ошибка" , MB_OK | MB_ICONHAND );
       return ( INIT_FAILED );
    }
  }
   else
  {
     datetime acs_time = GlobalVariableTime ( "not_eff_cnt" );
     datetime cur_time = TimeTradeServer ();
     if ( ( ulong ( cur_time ) - ulong ( acs_time ) ) > 7200 )
    {
       if ( MessageBox ( "Последняя запись в Счётчик неэффективных транзакций\n была произведена " + TimeToString ( acs_time ) +
       ". Нажмите 'OK' для\n обнуления переменных, или 'Cancel' для продолжения." , "Внимание" , MB_OKCANCEL | MB_ICONQUESTION ) == IDOK )
      {
         GlobalVariableSet ( "trans_count" , 0 );
         GlobalVariableSet ( "not_eff_cnt" , 0 );
      }
    }
  } 
   return ( INIT_SUCCEEDED ); 
}
//+------------------------------------------------------------------+
//| Expert Set start day time function                               |
//+------------------------------------------------------------------+
datetime SetStDayTime()
{
   MqlDateTime   dt_str;
   ulong one_day = 86400 ;
   TimeTradeServer ( dt_str );
   int hour = dt_str.hour;
  dt_str.hour = 19 ;
  dt_str.min = 0 ;
  dt_str.sec = 0 ;
   ulong time_start = ulong ( StructToTime ( dt_str ) );
//---   
   switch ( dt_str.day_of_week )
  {
     case 6 :  time_start -= one_day;
             break ;
     case 0 :  time_start -= one_day * 2 ;
             break ;
     case 1 :   if ( hour < 19 ) time_start -= one_day * 3 ;
             break ;
     default : if ( hour < 19 ) time_start -= one_day;
             break ;
  }
   return ( datetime ( time_start ) );
}
//+------------------------------------------------------------------+
//| Expert calc deals fee function                                   |
//+------------------------------------------------------------------+
double GetExgangeFee( const datetime start_time )
{
   double all_fee = 0.0 ;
   ulong deal_ticket;
//---  
   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 )
          {
            all_fee += HistoryDealGetDouble ( deal_ticket, DEAL_COMMISSION );
          }  
        }
      }
       return ( MathAbs ( all_fee ) );
    }  
  }
   return ( 0 );
}
//+------------------------------------------------------------------+
//| Expert set not effective transactions function                   |
//+------------------------------------------------------------------+
void SetNotEffTrans( const double tr_cnt )
{
   double a_cnt = tr_cnt + 1 ;
   datetime start_time = SetStDayTime();
   double tr_bonus = GetExgangeFee( start_time );
   if ( NormalizeDouble ( ( a_cnt * TrPoint - tr_bonus * DealPoint ), 0 ) > 0   )
  {
     double tr_count; 
     ulong i = 0 ;
     do
    {
      i++;
       if ( GlobalVariableGet ( "not_eff_cnt" , tr_count ) )
      {
         if ( GlobalVariableSetOnCondition ( "not_eff_cnt" , tr_count + 1 , tr_count ) )
        {
          i = 100 ;
        }
      }
    }  
     while ( i < 100 );
  }
}
//+------------------------------------------------------------------+
//| Expert Check limit transactions function                         |
//+------------------------------------------------------------------+
bool CheckLimitTrans()
{
   double a_count;
//---
   if ( GlobalVariableGet ( "not_eff_cnt" , a_count ) )
  {
     if ( a_count >= NotEff )
    {
       if ( !set_error )
      {
        set_error = true ; //чтобы один раз выводилось
         Print ( "Исчерпан лимит установки всех ордеров за торговый день!" );
      }
       return ( false );
    }  
  }
   else
  {
     Print ( "Не получено значение глобальной переменной 'not_eff_cnt'!" );
     return ( false );
  }
   return ( true );
}
//+------------------------------------------------------------------+
//| Expert Set transaction count function                            |
//+------------------------------------------------------------------+
void SetTransCount()
{
   double tr_count;
   uint i = 0 ;
   do
  {
    i++;
     if ( GlobalVariableGet ( "trans_count" , tr_count ) )
    {
       if ( GlobalVariableSetOnCondition ( "trans_count" , tr_count + 1 , tr_count ) )
      {
        i = 100 ;
      }
    }
  }  
   while ( i < 100 );
//---  
  SetNotEffTrans( tr_count );
}
//+------------------------------------------------------------------+
//| Expert Check trading time  function                              |
//+------------------------------------------------------------------+
void CheckResetTime()
{
   MqlDateTime trade_time;
   TimeTradeServer ( trade_time );
//---
   if ( trade_time.hour == 18 )
  {
     if ( ( trade_time.min > 45 ) && ( trade_time.min <= 49 ) )  
    {
       GlobalVariableSet ( "trans_count" , 0 );
       GlobalVariableSet ( "not_eff_cnt" , 0 );
      set_error = false ;
    }  
  }  
}
// По таймеру можно вызывать CheckResetTime(), чтобы в основной клиринг обнулить переменные
// Функция SetTransCount() вызвается после успешной отсылки ордера
// Функция CheckLimitTrans() вызвается перед каждой установкой ордера
 

자주 사용하고 유용한 기능:  

현재 날짜뿐만 아니라 보류 중인 주문 을 활성화하려면

요청에서 이를 지정해야 합니다(예시에서는 만료일이 표시됨).

(Sergey에게 감사) 최근 밝혀진 바와 같이 그러한 구현에서는 현재 미래와 다음 미래에서 작동합니다 .

더 먼 것들에서는 작동하지 않습니다!:

 int OnInit ()
{
  exp_day = GetCutTime( aSymbol );
   return ( INIT_SUCCEEDED );
}
//+------------------------------------------------------------------+
//| Expert Set expiration day function                              |
//+------------------------------------------------------------------+ 
datetime GetCutTime( const string t_symbol )
{
   MqlDateTime b_time;
   datetime a_time = datetime ( SymbolInfoInteger ( t_symbol, SYMBOL_EXPIRATION_TIME ) );
   TimeToStruct ( a_time, b_time );
  b_time.hour = 0 ;
  b_time.min = 0 ;
  b_time.sec = 0 ;
   return ( StructToTime ( b_time ) );
} 

//--- При установке и модификации ордера
  request.type_time = ORDER_TIME_SPECIFIED_DAY ;
  request.expiration = exp_day;
 

자주 사용하고 유용한 기능:   

파일에 설정 쓰기:

 //+------------------------------------------------------------------+
//| Expert Save settings function                                    |
//+------------------------------------------------------------------+
void SaveSettings()
{
   string file_name = _Symbol + ".dat" ;
   int file_handle;
   bool file_found = true ;
//---  
   if ( FileIsExist ( file_name, 0 ) )
  {
     if ( FileDelete ( file_name, 0 ) ) file_found = false ;
  }
   else
  {
    file_found = false ;
  }
//---
   if ( !file_found )
  {
    file_handle = FileOpen ( file_name, FILE_WRITE | FILE_BIN );
    
     if ( file_handle != INVALID_HANDLE )
    {
       FileWriteLong ( file_handle, e_high );
       FileWriteLong ( file_handle, a_profit );
       FileWriteLong ( file_handle, e_low );
       FileWriteLong ( file_handle, ord_delta_high );
       FileWriteLong ( file_handle, ord_delta_low );
       FileWriteLong ( file_handle, order_delta );
       FileWriteLong ( file_handle, exit_delta );
       FileClose ( file_handle );
    }
  } 
}

파일에서 설정 읽기:

 //+------------------------------------------------------------------+
//| Expert Load setings function                                     |
//+------------------------------------------------------------------+
void LoadSettings()
{
   string file_name = _Symbol + ".dat" ;
   int file_handle;
//---  
   if ( FileIsExist ( file_name, 0 ) )
  {
    file_handle = FileOpen ( file_name, FILE_READ | FILE_BIN );
    
     if ( file_handle != INVALID_HANDLE )
    {
      e_high = FileReadLong ( file_handle );
      a_profit = FileReadLong ( file_handle );
      e_low = FileReadLong ( file_handle );
      ord_delta_high = FileReadLong ( file_handle );
      ord_delta_low = FileReadLong ( file_handle );
      order_delta = FileReadLong ( file_handle );
      exit_delta = FileReadLong ( file_handle );
       FileClose ( file_handle );
    }
  } 
}
 

자주 사용하고 유용한 기능:  

고문을 계정에 바인딩:

 //+------------------------------------------------------------------+
//| Expert Check Account owner function                              |
//+------------------------------------------------------------------+
bool ExpCheckUser()
{
   long acc_login = long ( AccountInfoInteger ( ACCOUNT_LOGIN ) );
   string acc_user = AccountInfoString ( ACCOUNT_NAME );
  
   if ( ( acc_login == 12345 ) && ( acc_user == "Михайлов Михаил Михайлович" ) )
  {
     return ( true );
  }
   return ( false ); 
}
 

자주 사용하고 유용한 기능:   

핍을 상품 가격으로 변환하는 기능:

 double PointsToPrice( const long a_points )
{
   double step_price = SymbolInfoDouble ( _Symbol , SYMBOL_TRADE_TICK_SIZE );
   double a_price = ( double ( a_points ) * _Point ) / step_price;
  
   if ( a_points < 0 )
  {
    a_price = MathFloor ( a_price ) * step_price;
  }
   else
  {
    a_price = MathCeil ( a_price ) * step_price;
  }
  
   return ( NormalizeDouble ( a_price, _Digits ) );
}
사유: