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

 
voix_kas:

Результат:

Либо что-то я неправильно делаю (прошу поправить), либо многоуважаемый MetaDriver допустил ошибку в теории (при проектировании алгоритма). 

:)

Ну учитывая тот факт что "проектирование" алгоритма заняло около 3 минут (и минут 7 реализация), справился я неплохо :)  Целью же было показать рабочую  идею и уточнить постановку задачи.

И всё это оказалось в итоге полезным - у разработчиков появился реальный повод довести до ума функцию MathFloor() - в ней очевидно не всё чисто реализовано.

В итоге пришлось повозиться. Было весело. Устойчивую функцию (я про CountSignedDigits(double x)) удалось получить только через почти час экспериментов.

И то - даже сейчас не уверен что будет точно работать при всех входных значениях.  Автоматический стресс-тест не разрабатывал, сделал ручной.  Прошу тестить.

Ожидаю устойчивой работы до 10 десятичного знака после плавающей точки.

int CountSignedDigits(double x)
{
  for(int i=0; i<1000; i++,x*=10)
  {
    if(x-MathFloor(x+0.000000000005)<double(0.000000000005)) return i;
  }
  return -1;
}
Стресс-тест прилагается.  // Не стал убирать в коде некоторые промежуточные реализации. Оставил в коментах на попробовать/поразмышлять. В том числе разработчикам.
Файлы:
 
komposter:
1.  Не нужно определять dig для лота, достаточно нормализовать его до нужного шага:

2.  Даже если при передаче торгового запроса в переменную lot попадет мусор (в надцатом знаке после запятой), он должен будет отсеятся самим терминалом.

3.  По крайней мере, у меня за несколько лет использования такой конструкции проблем не возникало.

4.  А если хочется перестраховаться, можно воткнуть нормализацию до 8-го (с запасом) знака после запятой - если после "правильной" нормализации и появится мусор, то он будет намного дальше.

Первая идея правильная, остальные подозрительные. :)

Реализация рабочая для практики, но для искусственных условий определённых "проблем-стартером" (с) неточна. Ибо дискретные шаги порождает не относительно lot_min, а относительно нуля. :)

Однако поправить легко, если это заметить.

double komposterNormalizeLot(double lot, double lot_step, double lot_min, double lot_max)
{
   lot = NormalizeDouble( lot / lot_step, 0 ) * lot_step;
   if ( lot < lot_min ) lot = lot_min;
   if ( lot > lot_max ) lot = lot_max;
   return lot;
}
double metadriverNormalizeLot(double lot, double lot_step, double lot_min, double lot_max)
{
   lot = NormalizeDouble((lot-lot_min) / lot_step, 0) * lot_step + lot_min;
   if ( lot > lot_max ) lot = lot_max;
   return lot;
}

// Прошу эти перлы шибко всерьёз всё это не воспринимать. Уточнения чисто теоретические, для тренировки мозгов, поскольку на практике ни разу не видел lot_step равный, скажем 0.0231....

;)

 
metadriverNormalizeLot

вариант верный. Правильно учтён lot_min как в моей NL().

 

До кучи мой вариант. Учтите, что для некоторых инструментов шаг изменения цены больше пойнта.

//---------------------------------------------------------------------
//  Нормализация цены:
//---------------------------------------------------------------------
double
NormalizePrice( string _symbol, double _org_price )
{
  double  norm_price = _org_price;

  double  min_price_step = NormalizeDouble( current_tick_size / current_point, 0 );

  norm_price = NormalizeDouble( NormalizeDouble(( NormalizeDouble( _org_price / current_point, 0 )) / min_price_step, 0 ) * min_price_step * current_point, current_digits );

  return( norm_price );
}

//---------------------------------------------------------------------
//  Вычисление лота:
//---------------------------------------------------------------------
double
NormalizeLot( double _required_lot )
{
  double        lot, k;

  if( current_min_lot_step > 0 )
  {
    k = 1.0 / current_min_lot_step;
  }
  else
  {
    k = 1.0 / current_min_permitted_lot;
  }

  lot = MathFloor( _required_lot * k ) / k;

  if( lot < current_min_permitted_lot )
  {
   lot = current_min_permitted_lot;
  }

  if( lot > current_max_permitted_lot )
  {
    lot = current_max_permitted_lot;
  }

  lot = NormalizeDouble( lot, 2 );
  return( lot );
}
 

Если принять за аксиому, что шаги "идут" не от нуля, а от минимального лота, правильный алгоритм следующий:

double voixkasNormalizeLot(double lot, double lot_step, double lot_min, double lot_max)
{
  if ( lot < lot_min ) lot = lot_min;
  else lot = NormalizeDouble((lot-lot_min) / lot_step, 0) * lot_step + lot_min;

  if ( lot > lot_max ) lot = lot_max;
  return NormalizeDouble(Lot, 8);
}

В варианте Компостера шаги "идут" от нуля. Что, как мне кажется, не правильно.
В варианте МетаДрайвера код пропускает отрицательное значение. =Р

 
voix_kas:
...

В варианте МетаДрайвера код пропускает отрицательное значение. =Р

:))  ..... Ах так! Да у тебя вапче работать не будет!!  ;-Р  ;-Ь  ;-Р

double voixkasNormalizeLot(double lot, double lot_step, double lot_min, double lot_max)
{
  if ( lot < lot_min ) lot = lot_min;
  else lot = NormalizeDouble((lot-lot_min) / lot_step, 0) * lot_step + lot_min;

  if ( lot > lot_max ) lot = lot_max;
  return NormalizeDouble(Lot, 8);
}

Ну если уж на то пошло, то самый короткий и при этом "типа точный"  вариант такой:

double mdNormalizeLot(double lot, double lot_step, double lot_min, double lot_max)
{
  lot = MathMin(lot, lot_min);
  lot = NormalizeDouble((lot-lot_min) / lot_step, 0) * lot_step + lot_min;
  return NormalizeDouble(MathMin(lot, lot_max), MathMax(CountSignedDigits(lot_min),CountSignedDigits(lot_step));
}

И это ещё без проверки на нулёвость и отрицательность lot_step, lot_min и lot_max !!......

:))))

 

Ыыы... задел за живое. :)) Последнюю строку вручную правил в сообщении на форуме, так что простительно. =)
Кстати, твой код тоже не компилируется (в последней строке закрывающую скобку забыл). :-Р
К тому же, работает он в 2-3 раза медленнее (сейчас замерил на скрипте), а качество проверки такое же. :-Р 

В общем, пока нет грамотного кода по определению значащего младшего разряда, воспользуюсь советом Компостера: нормализировать объем до 8-го знака после запятой.
Надеюсь, подводных камней не появится.

Всем спасибо за помощь.

 

смешные вы ребята как я погляжу.

в своём первом посте дал NL() до чего вы через две страницы только дошли ;)

 

Появился еще один вопрос к гуру. При тестировании мультивалютника возникают ошибки (скрин прилагаю).
Пытаюсь совершить торговую операцию, на что получаю ответ: нет цены. По тестеру видно, что котировки по данной паре начинают поступать в 2011.01.03 01:00:00, в то время как тоже EURUSD котируется с  2011.01.03 00:00:00  Можно ли как-то узнать, время начала котировок, чтобы обойти данную ошибку?

Скрин с ошибкой 

 
voix_kas:

Появился еще один вопрос к гуру. При тестировании мультивалютника возникают ошибки (скрин прилагаю).
Пытаюсь совершить торговую операцию, на что получаю ответ: нет цены. По тестеру видно, что котировки по данной паре начинают поступать в 2011.01.03 01:00:00, в то время как тоже EURUSD котируется с  2011.01.03 00:00:00  Можно ли как-то узнать, время начала котировок, что обойти данную ошибку?

 

Торговые и котировочные сессии не помогут проблему решить?
Причина обращения: