FORTS: Um Anfängern zu helfen - Seite 2

 
Михаил:

Dann sind Sie der erste Anwärter auf den Titel "Bester Pupua Coder 2015".

P/S Bitte fallen Sie nicht vor Lachen vom Stuhl :)

Werden Sie wütend, werden Sie wütend, wenn Sie vier Codezeilen nicht verstehen (absichtlich vier statt zwei, damit es leichter zu verstehen ist)

Wo liegt das Problem? Es ist nicht klar, was die Nummer 86400 ist? Oder 3600?

86400 ist eine Anzahl von Sekunden an einem Tag. 3600 - in einer Stunde.

ps. Was ist das für ein Lachen? Hier muss man weinen.

 

Häufig verwendete und nützliche Funktionen:

Die Funktion SetStDayTime() funktionierte nicht sehr schnell, so dass

Ich stelle eine neu gestaltete Version ein (Dank an Sergei):

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

Merkmale:

Empfangsbestätigung (TRADE_RETCODE_PLACED ) im OrderSend()-Returncode und Auftragsticket,

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

und für die Funktion OrderSendAsync() in OnTradeTransaction() bedeutet dies keineswegs, dass

der Auftrag wird tatsächlich an eine Börse ÜBERTRAGEN.

Daher ist eine zusätzliche Prüfung des Auftragsstatus erforderlich (wie auch bei anderen Aktionen auf dem Auftrag).

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

Es gibt einen Tippfehler inCheckOrderState().

Anstelle voninit_volume == init_volume

es sollteinit_volume == cur_volume sein

 

Häufig verwendete und nützliche Funktionen:

CheckOrderState() wurde umgestaltet und heißt jetzt OrderRealSelect() mit der Option, keine Daten über die Bestellung zu erhalten/zu empfangen

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


Wenn wir einen Auftrag ändern oder löschen wollen, müssen wir nur wissen, dass er existiert:

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

Wenn wir nach der Löschung Daten über die Bestellung benötigen, dann:

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

Im Falle eines Fehlers:

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

Häufig verwendete und nützliche Funktionen:

Neu gestaltete Funktionen zur Zählung ineffizienter Transaktionen:

//+------------------------------------------------------------------+
//|                                                     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() вызвается перед каждой установкой ордера
 

Häufig verwendete und nützliche Funktionen:

Wenn wir wollen, dass der schwebende Auftrag nicht nur am aktuellen Tag aktiv ist, dann

die Sie in Ihrem Antrag angeben sollten (in diesem Beispiel ist der Verfallstag angegeben)

(Danke Sergey) Wie sich kürzlich herausstellte, funktioniert diese Implementierung sowohl für die aktuelle als auch für die nächste Zukunft.

Es funktioniert NICHT bei längeren Terminen!

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;
 

Häufig verwendete und nützliche Funktionen:

Schreiben der Einstellungen in eine Datei:

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

Lesen von Einstellungen aus einer Datei:

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

Häufig verwendete und nützliche Funktionen:

Verknüpfung eines EA mit einem Konto:

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

Häufig verwendete und nützliche Funktionen:

Funktion zur Umrechnung von Punkten in den Preis eines Instruments:

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