FORTS:帮助初学者 - 页 2

 
Михаил:

那么,你就是 "2015年最佳Pupua Coder "称号的第一个竞争者。

P/S 请不要笑得从椅子上掉下来 :)

生气,生气,如果你搞不清楚四行代码(特意用四行而不是两行来使其更容易理解)。

有什么问题呢?不清楚86400号是什么?还是3600?

86400是一天中的一个秒数。3600 - 在一个小时内。

ps.这是什么样的笑声?你必须在这里哭。

 

经常使用和有用的功能

SetStDayTime()函数的工作速度并不快,所以

我贴出一个重新设计的(感谢谢尔盖)。

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 );
    }
  } 
}
 

经常使用和有用的功能

将一个EA链接到一个账户。

//+------------------------------------------------------------------+
//| 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 ) );
}
原因: