Order price has more digits than symbol allows. Allowed 3 digits

douglascvas's avatar

douglascvas since: 02 Jan 2018;

  13 Oct 2021, 12:56
Order price has more digits than symbol allows. Allowed 3 digits

Hi, I'm trying to open a pending order via OpenAPI using the ProtoOANewOrderReq but the request is failing with this error:

Order price = 131.07400024414062 has more digits than symbol allows. Allowed 3 digits

What does that mean? The ProtoOANewOrderReq object in Java expects a "double" as the type for the StopPrice, how am I supposed to specify how many digits it will send to the API? Also where does this amount of digits come from? I can't even find anything related in the documentation.

I really appreciate any help.

amusleh's avatar

amusleh since: 01 Mar 2021;

  13 Oct 2021, 14:30

Hi,

The decimal places of your stop price must much with symbol digits.

You can get the symbol digits from ProtoOASymbol.

Community Developer | Spotware | Telegram: @algodeveloper
douglascvas's avatar

douglascvas since: 02 Jan 2018;

  15 Oct 2021, 10:56
RE:

 amusleh said:

Hi,

The decimal places of your stop price must much with symbol digits.

You can get the symbol digits from ProtoOASymbol.

As I said, that's weird because the value is a double, so I don't understand why I need to round it before sending. Anyway, using bigdecimal fixes that one problem:

request.setStopPrice(BigDecimal.valueOf(order.getTargetPrice())
                    .setScale(symbol.getDigits(), RoundingMode.HALF_UP)
                    .doubleValue());

Now I get another one in the relative price. And that one I can't see how to fix

request.setRelativeStopLoss((long) (stopLossPips * symbol.getPipSize() * 100000));

That gives me this error:

Error:Relative stop loss has invalid precision

How can that be if the field is a Long? There is absolutely no way to set decimal precision. I don't understand what is going on.

The .proto file states this:

optional int64 relativeTakeProfit = 20; // Relative Take Profit that can be specified instead of the absolute one. Specified in 1/100000 of unit of a price. For BUY takeProfit = entryPrice + relativeTakeProfit, for SELL takeProfit = entryPrice - relativeTakeProfit.​
amusleh's avatar

amusleh since: 01 Mar 2021;

  15 Oct 2021, 13:07
RE: RE:

douglascvas said:

 amusleh said:

Hi,

The decimal places of your stop price must much with symbol digits.

You can get the symbol digits from ProtoOASymbol.

As I said, that's weird because the value is a double, so I don't understand why I need to round it before sending. Anyway, using bigdecimal fixes that one problem:

request.setStopPrice(BigDecimal.valueOf(order.getTargetPrice())
                    .setScale(symbol.getDigits(), RoundingMode.HALF_UP)
                    .doubleValue());

Now I get another one in the relative price. And that one I can't see how to fix

request.setRelativeStopLoss((long) (stopLossPips * symbol.getPipSize() * 100000));

That gives me this error:

Error:Relative stop loss has invalid precision

How can that be if the field is a Long? There is absolutely no way to set decimal precision. I don't understand what is going on.

The .proto file states this:

optional int64 relativeTakeProfit = 20; // Relative Take Profit that can be specified instead of the absolute one. Specified in 1/100000 of unit of a price. For BUY takeProfit = entryPrice + relativeTakeProfit, for SELL takeProfit = entryPrice - relativeTakeProfit.​

Hi,

You should round the multiplication result before converting it back to long, ex:

        public static long GetRelativeFromPips(this ProtoOASymbol symbol, double pips)
        {
            var pipsInPrice = pips * symbol.GetPipSize();

            return (long)Math.Round(pipsInPrice * 100000, symbol.Digits);
        }

If you pass 10 pips for above method it will first multiply it by symbol pip size, for example EURUSD pip size is 0.0001, then it will multiply it to 100000 and then it rounds the multiplication result back to symbol digits.

Community Developer | Spotware | Telegram: @algodeveloper