Errors, bugs, questions - page 443

 
voix_kas:

Result:

Either I'm doing something wrong (please correct), or MetaDriver made a mistake in theory (when designing the algorithm).

:)

Well, considering the fact that algorithm "design" took about 3 minutes (and 7 minutes of implementation), I did pretty well :) The aim was to show working idea and to clarify the problem statement.

And all this turned out to be useful - the developers had a real opportunity to improve MathFloor() function - obviously it is not entirely cleanly implemented.

In the end they had to tinker with it. It was fun. I managed to get a stable function (I mean CountSignedDigits(double x)) only after almost an hour of experiments.

And even now I'm not sure it will work correctly with all the input values. I haven't developed an automated stress-test, I've made a manual one. Please test it.

I expect stable operation up to 10 decimal places after floating point.

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;
}
Stress-test attached. // I did not remove some intermediate realizations from the code. I left it in comments for you to try/think. Including the developers.
Files:
 
komposter:
1. you don't need to define dig for a lot, just normalize it to the right step:

2. even if there is some rubbish in the lot variable when sending a trade request (in the decimal place), it should be discarded by the terminal itself.

At least, I haven't had any problems during several years of using such a construct.

4. If you want to insure, you can normalize it to 8 decimal places (with a margin) - if there's rubbish after "correct" normalization, it will be much farther.

The first idea is correct, the others are suspect. :)

The implementation is workable for practice, but for artificial conditions defined by "problem-starter" (c) is inaccurate. For discrete steps generates not relative to lot_min, but relative to zero. :)

However, it is easy to fix, if you notice it.

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

// Please do not take all these pearls too seriously. Clarifications are purely theoretical, for brain training, because in practice I've never seen lot_step equal to, say, 0.0231....

;)

 
metadriverNormalizeLot

variant is correct. Correctly accounted for by lot_min as in my NL().

 

My variant is also available. Note that for some instruments the price change step is larger than the point.

//---------------------------------------------------------------------
//  Нормализация цены:
//---------------------------------------------------------------------
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 );
}
 

If we assume as an axiom that the steps "go" not from zero, but from the minimum lot, the correct algorithm is as follows:

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

In the Composter version, the steps "go" from zero. Which does not seem right to me.
In the MetaDriver variant, the code skips a negative value. =Р

 
voix_kas:
...

In the MetaDriver variant, the code skips a negative value. =Р

:)) ..... Oh so! You won't work at all! ;-R ;-b ;-R

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(L ot, 8);
}

Well, if anything, the shortest and at the same time "sort of accurate" variant is this:

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

And that's without checking for nullity and negativity of lot_step, lot_min and lot_max!!......

:))))

 

Uh... hit a nerve. :)) The last line was hand-corrected in a forum post, so forgive me. =)
By the way, your code didn't compile either (I forgot to put a closing parenthesis in the last line). :-Р
Besides it's 2-3 times slower (now I've checked it on script), but quality of check is the same. :-Р

Anyway, as long as there's no proper code to determine the significant integer, I'll take Composter's advice: normalize volume to 8 decimal places.
Hopefully there will be no pitfalls.

Thank you all for your help.

 

you guys are funny I see.

in your first post gave NL() what you only got to two pages later ;)

 

There is another question for the gurus. When I test the multicurrency, I get errors (screenshot attached).
I am trying to make a trade operation, but I get an answer: No price. According to the tester it can be seen that quotes for this pair start coming in 2011.01.0301:00:00, while EURUSD is also quoted from 2011.01.0300:00:00 Is there any way to find out the time of the start of quotes to bypass this error?

Screenshot with error

 
voix_kas:

There is another question for the gurus. When I test the multicurrency, I get errors (screenshot attached).
I am trying to make a trade operation, but I get an answer: No price. According to the tester it can be seen that quotes for this pair start coming in 2011.01.0301:00:00, while EURUSD is also quoted from 2011.01.0300:00:00Is there any way to find out the time of the start of quotes to avoid this error?

Trading and quoting sessions will not help to solve the problem?
Reason: