Ошибки, баги, вопросы - страница 3445

 
Carl Schreiber #:

Однако это не значит, что так будет всегда. С другим брокером, возможно, с большей задержкой, менее быстрым сервером для более простых учетных записей... эти данные могут прийти не сразу. Думаю, если спросить напрямую у MQ, то они ответят, что не могут этого гарантировать.

Можно видеть, что ваш класс, как и структура fxsaber или статические переменные в функциях, инициализируются и заполняются до запуска OnInit(). А что, если эти данные поступят немного позже? Помню, в тестере исторические котировки индикаторов могли запаздывать и приходилось делать дополнительную проверку в основной функции...

Следовательно, как убедиться ? «Сон (1000)» в OnInit()?

However, this does not mean that it will always be like this. With another broker, with maybe more latency, a less fast server for simpler accounts, ..., this data may not arrive immediately. I think if you ask MQ directly, they will answer that they cannot guarantee that.

One can see that your class, like the structure of fxsaber or the static variables in the functions, are initialized and filled before OnInit() is started. But what if this data arrives a little later? I remember that in the tester the historic quotes for the indicators might come to late and I had to do an extra check in the main function...

Ergo, how to make sure? A "Sleep(1000)" in OnInit()?

Вы упускаете ещё один важный момент в статических переменных. Согласно документации статическая переменная может быть инициализирована «соответствующей ее типу константой или константным выражением» но функция не является ни константой, ни константным выражением и соответственно переменной присваивается значение при каждом выполнении функции. То-есть точно так же как и для обычной переменной.

Sleep(1000)" in OnInit() никак не поможет. Полностью загружен советник только после выполнения инициализации.

А вот с инициализацией в конструкторе класса надо экспериментировать. Конечно есть подозрение, что может быть ошибка, но без экспериментов не понять…

 
Alexey Viktorov # :

Вы упускаете ещё один важный момент в статических переменных. Согласно документации статическая переменная может быть инициализирована «соответствующей ее типу константой или константным выражением» но функция не является ни константой, ни константным выражением и соответственно переменной присваивается значение при каждом выполнении функции. То-есть точно так же как и для обычной переменной.

Sleep(1000)" in OnInit() никак не поможет. Полностью загружен советник только после выполнения инициализации.

А вот с инициализацией в конструкторе класса надо экспериментировать. Конечно есть подозрение, что может быть ошибка, но без экспериментов не понять…

Сначала я хотел использовать такие значения, как SYMBOL_TRADE_TICK_SIZE, SYMBOL_VOLUME_STEP,... в качестве статических переменных только в тех функциях, где они необходимы. Но что, если при запуске им не присвоено никакого значения? Затем я возвращаюсь к запросу или проверке при каждом вызове функции :(
Это также применимо к глобальным структурам и классам.

Поэтому теперь я решил сохранить эти ключевые значения в глобальных переменных, которые назначаются в дополнительной функции в OnInit(). Наверняка сон там сработает?

At first I wanted to use values like SYMBOL_TRADE_TICK_SIZE, SYMBOL_VOLUME_STEP, ... as static variables only in the functions where they are needed. But what if no value is assigned to them at startup? Then I'm back to a query or check with every function call :(
This would also apply to global structures and classes.

So now I decided to store these key values in global variables, which are assigned in an extra function in OnInit(). Surely a sleep will work there?

#define _d2D(p)               (fabs(p)>0.00000001 ? DoubleToString(p,_Digits) : DoubleToString(p,1)) // to get 0.0 instead of 0.00000
...
double         DELTA,dDEVI,LevSTP,LevFRZ,VolMin,VolMax,VolStp,ValTCK,SzeTCK;
...

bool setGlobVars() {
   // It is very likely that the values will be filled the very first time, but this is not guaranteed.
   // And due to the importance of theses values for the trading ...
   
   dDEVI   = LevSTP  = LevFRZ  = DELTA = VolMin = VolMax = VolStp = 0.0;
   
   int i=100;
   while (i-->0) {   // no endless loop
      dDEVI   = 10 * _Point;
      LevSTP  = _Point * SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL);
      LevFRZ  = _Point * SymbolInfoInteger(_Symbol, SYMBOL_TRADE_FREEZE_LEVEL);
      SzeTCK  = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
      ValTCK  = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
      VolMin  = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
      VolMax  = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
      VolStp  = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
      
      if ( dDEVI>FLT_MIN && LevSTP>FLT_MIN && LevFRZ>FLT_MIN && ValTCK>FLT_MIN && SzeTCK>FLT_MIN && VolMin>FLT_MIN && VolMax>FLT_MIN && VolStp>FLT_MIN )
      break;    // ready fine
      Sleep(100);  // next round
   }
   if (i>1) {
      DELTA = ValTCK / SzeTCK;  // SzeTCK must be != 0.0
      return(true);
   }
   logNewErr(FunLine,0,StringFormat("IMPORTANT trade values are ZERO, did not arrive from the server, last Ping: %i!!"+
                                    "%sdDEVI:%s LevSTP:%s LevFRZ:%s ValTCK:%s SzeTCK:%s VolMin:%s VolMax:%s VolStp:%s",TerminalInfoInteger(TERMINAL_PING_LAST),
                                    _newL, _d2D(dDEVI), _d2D(LevSTP), _d2D(LevFRZ), _d2D(ValTCK), _d2D(SzeTCK), _d2D(VolMin), _d2D(VolMax), _d2D(VolStp)));
   logSndTrd(FunLine,0);
   return(false);
}
int OnInit()
   {
      bool ok = setGlobVars();
   }
 
Carl Schreiber #:

Сначала я хотел использовать такие значения, как SYMBOL_TRADE_TICK_SIZE, SYMBOL_VOLUME_STEP,... в качестве статических переменных только в тех функциях, где они необходимы. Но что, если при запуске им не присвоено никакого значения? Затем я возвращаюсь к запросу или проверке при каждом вызове функции :(
Это также применимо к глобальным структурам и классам.

Поэтому теперь я решил сохранить эти ключевые значения в глобальных переменных, которые назначаются в дополнительной функции в OnInit(). Наверняка сон там сработает?

At first I wanted to use values like SYMBOL_TRADE_TICK_SIZE, SYMBOL_VOLUME_STEP, ... as static variables only in the functions where they are needed. But what if no value is assigned to them at startup? Then I'm back to a query or check with every function call :(
This would also apply to global structures and classes.

So now I decided to store these key values in global variables, which are assigned in an extra function in OnInit(). Surely a sleep will work there?

во первых при OnInit может вообще не быть связи с торговым сервером, то есть придётся самому генерировать событие OnConnect и уже там инициализировать эти переменные

во вторых STOP_LEVEL меняется часто, и даже VOLUME_MIN, VOLUME_STEP, LEVERAGE (точнее MARGIN_INITIAL, для открытия позиций) могут быть изменены динамически.

 
Carl Schreiber #:

структура fxsaber инициализируются и заполняются до запуска OnInit().

Это не так. Структура в режиме заполнения до тех пор, пока не будут получены ненулевые значения.
 
fxsaber # :
Это не так. Структура в режиме заполнения до тех пор, пока не будут получены ненулевые значения.

Не могли бы вы объяснить это более подробно, возможно, со ссылкой?

Would you mind to explain this in more detail, perhaps with a link?
 
Carl Schreiber #:

Не могли бы вы объяснить это более подробно, возможно, со ссылкой?

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Ошибки, баги, вопросы

fxsaber, 2024.01.01 19:36

struct STRUCT_SYMBOL_INFO_DOUBLE
{
  double Prop[100];
  
  double Get( const ENUM_SYMBOL_INFO_DOUBLE Prop_ID )
  {
    return(this.Prop[Prop_ID] ? this.Prop[Prop_ID]
                              : this.Prop[Prop_ID] = ::SymbolInfoDouble(_Symbol, Prop_ID));        
  }
} SymbolDouble = {};


void OnInit()
{
  Print(SymbolDouble.Get(SYMBOL_VOLUME_MIN));
  Print(SymbolDouble.Get(SYMBOL_VOLUME_MAX));
  Print(SymbolDouble.Get(SYMBOL_VOLUME_STEP));
}
Это условие будет вызывать SymbolInfoDouble только в том случае, если до этого возвращался ноль. Как только придет ненулевое значение, больше SymbolInfoDouble вызываться не будет - значение будет браться из структуры.
 
fxsaber #:
Это условие будет вызывать SymbolInfoDouble только в том случае, если до этого возвращался ноль. Как только придет ненулевое значение, больше SymbolInfoDouble вызываться не будет - значение будет браться из структуры.

Интересный костыль, без иронии. А что произойдёт если ::SymbolInfoDouble(_Symbol, Prop_ID) вернёт ошибку?

 
fxsaber #:
Это условие будет вызывать SymbolInfoDouble только в том случае, если до этого возвращался ноль. Как только придет ненулевое значение, больше SymbolInfoDouble вызываться не будет - значение будет браться из структуры.

Я вижу, что в OnInit() структура заполняется, но только там(?) и только один раз(?). Что делать, если OnInit() вызывается в то время, когда соединение с сервером было слишком медленным или временно разорвано, так что функции MQ возвращают ноль вместо реального значения брокера?

Well I see that in OnInit() the structure is filled, but only there(?) and only once(?). What when OnInit() is called while the connection to the server was too slow or temporarily broken so that the MQ functions return zero instead of the real broker value?

 
Carl Schreiber #:

Я вижу, что в OnInit() структура заполняется, но только там(?) и только один раз(?). Что делать, если OnInit() вызывается в то время, когда соединение с сервером было слишком медленным или временно разорвано, так что функции MQ возвращают ноль вместо реального значения брокера?

Well I see that in OnInit() the structure is filled, but only there(?) and only once(?). What when OnInit() is called while the connection to the server was too slow or temporarily broken so that the MQ functions return zero instead of the real broker value?

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Ошибки, баги, вопросы

Artyom Trishkin, 2024.01.02 08:42

Если данные не получены - повторить запрос. Если опять нет, то вписать их при старте. 

 

СимволInfoDouble() возвращает только эти ошибки:

SymbolInfoDouble() returns only these Errors:
The value of double type. In case of execution failure, information about the error can be obtained using GetLastError() function:
•5040 – invalid string parameter for specifying a symbol name,
•4301 – unknown symbol (financial instrument),
•4302 – symbol is not selected in "Market Watch" (not found in the list of available ones),
•4303 – invalid identifier of a symbol property.

No Error in case of connection problem.

Нет Ошибка в случае проблем с подключением.