Adjust StopLoss to ticksize

 

Hello, I made a trade asistant which works on forex, but on futires not.

This asistant works like this, I click on the chart, and there it will be stoploss, and if click is below Bid it will open a Buy and if click is above Ask it will open a sell.

The thing is that for some MiniS&P for example prices are multiple of 0.25 ( ticksize = 0.25)

How can I round the price that I get from mouse clik, to closest multiple of 0.25?

Thanks!

 
Daniel Cioca:

Hello, I made a trade asistant which works on forex, but on futires not.

This asistant works like this, I click on the chart, and there it will be stoploss, and if click is below Bid it will open a Buy and if click is above Ask it will open a sell.

The thing is that for some MiniS&P for example prices are multiple of 0.25 ( ticksize = 0.25)

How can I round the price that I get from mouse clik, to closest multiple of 0.25?

Thanks!

I would make the price integer and use the remainder of the division.

Just typed in 5 minutes. To show an idea. This is not a ready-to-use code and may be wrong.

#property strict
#property script_show_inputs

input double inpPrice   = 1.1234567;
input double inpRoundTo = 0.25;

void OnStart()
  {
   double result = example(inpPrice, inpRoundTo);
   Alert(StringFormat("price %s, round_to %s, result %s", prcToStr(inpPrice), prcToStr(inpRoundTo), prcToStr(result)));
  }

double example(double price, double roundTo)
  {
   int int_price = priceToInt(price * MathPow(10, _Digits));
   int int_roundTo = priceToInt(roundTo * MathPow(10, _Digits));
   int remainder = int_price % int_roundTo;
   if(remainder != 0)
      int_price += remainder < NormalizeDouble(int_roundTo / 2.0, 0) ? -remainder : int_roundTo - remainder;
   return(NormalizeDouble(int_price * _Point, _Digits));
  }

int priceToInt(double value)
  {
   return(int(NormalizeDouble(value, 0)));
  }

string prcToStr(double price)
  {
   return(DoubleToString(price, _Digits));
  }


 

William gave an adequate solution, and I'm not looking for easy ways😄😄😄

The right way:

An example of how not to do it:

Forum on trading, automated trading systems and testing trading strategies

Adjust StopLoss to ticksize

Vladislav Boyko, 2023.03.24 20:06

I would make the price integer and use the remainder of the division.

Just typed in 5 minutes. To show an idea. This is not a ready-to-use code and may be wrong.

#property strict
#property script_show_inputs

input double inpPrice   = 1.1234567;
input double inpRoundTo = 0.25;

void OnStart()
  {
   double result = example(inpPrice, inpRoundTo);
   Alert(StringFormat("price %s, round_to %s, result %s", prcToStr(inpPrice), prcToStr(inpRoundTo), prcToStr(result)));
  }

double example(double price, double roundTo)
  {
   int int_price = priceToInt(price * MathPow(10, _Digits));
   int int_roundTo = priceToInt(roundTo * MathPow(10, _Digits));
   int remainder = int_price % int_roundTo;
   if(remainder != 0)
      int_price += remainder < NormalizeDouble(int_roundTo / 2.0, 0) ? -remainder : int_roundTo - remainder;
   return(NormalizeDouble(int_price * _Point, _Digits));
  }

int priceToInt(double value)
  {
   return(int(NormalizeDouble(value, 0)));
  }

string prcToStr(double price)
  {
   return(DoubleToString(price, _Digits));
  }



 
Vladislav Boyko #:

William gave an adequate solution, and I'm not looking for easy ways😄😄😄

The right way:

An example of how not to do it:


Thank you! 
 
Your code
price * MathPow(10, _Digits)
Simplified
price / _Point
 
William Roeder #:
Your code
Simplified

It's done on purpose. Because:

(_Point == 1.0 / MathPow(10, _Digits)) // I have no reason to believe that this expression will always be true

This is a reinsurance against the case when _Point is greater. Although, I have no reason to believe that this could be. Just in case...

 
William Roeder #:
Your code
Simplified

But this code definitely needs optimization / simplification (if it is still used despite the fact that your version is better).

For example, this can be calculated once on initialization:

double example(double price, double roundTo)
  {
   int int_price = priceToInt(price * MathPow(10, _Digits));
   int int_roundTo = priceToInt(roundTo * MathPow(10, _Digits));
   int remainder = int_price % int_roundTo;
   if(remainder != 0)
      int_price += remainder < NormalizeDouble(int_roundTo / 2.0, 0) ? -remainder : int_roundTo - remainder;
   return(NormalizeDouble(int_price * _Point, _Digits));
  }

Since most likely it will not be a script

Reason: