Invalid price, weird price format after conv to double

 

Hello,

I'm gathering price from CSV and want to convert it from string to double. The flow is like this:

double price = StrToDouble(FileReadString(handle))

When I use Print to show the converted number it gives me correct value. For example 98.567. But when I want to place order with this price - it tells me that price is invalid (I don't know these zeros where are from):

Invalid price 98.5670000 for OrderSend
 
burnhype:

Hello,

I'm gathering price from CSV and want to convert it from string to double. The flow is like this:

When I use Print to show the converted number it gives me correct value. For example 98.567. But when I want to place order with this price - it tells me that price is invalid (I don't know these zeros where are from):

Use NormalizeDouble().

double price = NormalizeDouble (StrToDouble(FileReadString(handle)), Digits);
 
paladin80: Use NormalizeDouble()

It is never necessary to normalizeDouble, ever. It's a cludge, don't use it.

Bid/Ask: (No Need) to use NormalizeDouble in OrderSend - MQL4 forum

Can price != price ? - MQL4 forum

 
WHRoeder:

It is never necessary to normalizeDouble, ever. It's a cludge, don't use it.

Bid/Ask: (No Need) to use NormalizeDouble in OrderSend - MQL4 forum

Can price != price ? - MQL4 forum


To open position at the currenct price - Ask or Bid must be used in OrderSend(). But if someone wants to place pending order or StopLoss/TakeProfit the value must be normalized.

double NormalizeDouble( double value, int digits)
Rounds the floating point value to the given precision. Returns normalized value of the double type.
The calculated StopLoss and TakeProfit values, as well as open price of pending orders must be normalized with a precision the value of which is stored in the pre-defined variable of Digits.
 
burnhype: But when I want to place order with this price - it tells me that price is invalid
Invalid price 98.5670000 for OrderSend
  1. Are you trying to open a Buy or sell, you have to use Ask and Bid not some arbitrary value
  2. Are you trying to open a BuyLimit or BuyStop, are you using the correct one.
  3. Are you trying to open a BuyLimit or BuyStop, if Point != TickSize (metals) the price must be adjusted (NOT NormalizeDouble,) just like lotSize must be.
    double NormalizePrice(double p, string pair=""){
        // https://forum.mql4.com/43064#515262 zzuegg reports for non-currency DE30:
        // MarketInfo(chart.symbol,MODE_TICKSIZE) returns 0.5
        // MarketInfo(chart.symbol,MODE_DIGITS) return 1
        // Point = 0.1
        // Prices to open must be a multiple of ticksize
        if (pair == "") pair = Symbol();
        double ts = MarketInfo(pair, MODE_TICKSIZE)
        return( MathRound(p/ts) * ts );
    }
    double NormalizeLots(double lots, string pair=""){
        if (pair == "") pair = Symbol();
        double  lotStep     = MarketInfo(pair, MODE_LOTSTEP),
                minLot      = MarketInfo(pair, MODE_MINLOT);
        lots    = MathRound(lots/ls) * ls;
        if (lots < minLot) lots = 0;    // or minLot
        return(lots);
    }
    

  4. Are you trying to open a BuyLimit or BuyStop, have you verified that the open price is beyond market by MarketInfo(chart.symbol, MODE_STOPLEVEL)*Point
  5. Have you adjust for 4/5 digit brokers (tp, sl, AND SLIPPAGE?) Have you adjusted for ECN brokers?
  6. Have you shown your code? There's no mind readers here.
 
paladin80:

The calculated StopLoss and TakeProfit values, as well as open price of pending orders must be normalized with a precision the value of which is stored in the pre-defined variable of Digits.

WRONG .

I have NO normalizeDouble anywhere in my code. Works fine.

See the link in my previous post. Only the pending open price must be adjusted and NOT to Digits, NOT to Point, but to ticksize. If ticksize != point, NormalizeDouble will NOT work.

If ticksize == point, the pending open price doesn't need to be adjust as any double is a valid price (as digits below Digits are ignored)

 
WHRoeder:

If ticksize == point, the pending open price doesn't need to be adjust as any double is a valid price (as digits below Digits are ignored)


I'm pretty sure that is incorrect, sometimes I have entry prices that are calculated, if I use them as is I can get an error 4107
 

I'm checking for signals from CSV

void Signal_check(string symbol) {
  string name = "orders\\" + symbol + ".csv";
  int handle = FileOpen(name, FILE_CSV | FILE_READ, ',');
  if(handle < 1) {
    //Print("NOTICE: No valid signal for ", symbol);
  } else {
    string type = FileReadString(handle);
    double lots = StrToDouble(FileReadString(handle));
    double price = StrToDouble(FileReadString(handle));
    double stop = StrToDouble(FileReadString(handle));
    double target = StrToDouble(FileReadString(handle));
    
    FileClose(handle);
    
    if(type != "BUY" && type != "SELL") {
      Print("ERROR: Invalid type in signal in CSV");
      return;
    }
    
    if(lots <= 0) {
      Print("ERROR: Invalid lots in CSV");
      return;
    }
    
    if(price <= 0) {
      Print("ERROR: Invalid price in CSV");
      return;
    }
    
    if(stop <= 0) {
      Print("ERROR: Invalid stop in CSV");
      return;
    }
    
    if(target <= 0) {
      Print("ERROR: Invalid target in CSV");
      return;
    }
    
    int last_order = Order_last(symbol);
    if(last_order > 0) {
      Print("WARNING: Closing order #", last_order);
      Order_close(last_order);
    }
    
    int order = Order_new(symbol, type, lots, price, stop, target);
    if(order < 0) {
      Print("ERROR: Cannot insert order from signal");
      return;
    } else {
      Print("NOTICE: Order inserted propely");
      FileDelete(name);
      return;
    }
  }
}

And then trying to send order

int Order_new(string symbol, string type, double volume, double price, double stop, double target) {
  int cmd;
  int ticket;
  int stoplevel = MarketInfo(symbol, MODE_STOPLEVEL);
  
  if(Order_count() >= 6) {
    Print("ERROR: There can be only 6 orders a time.");
    return(-1);
  }
  
  if(type == "BUY") {
    if(((price / Point) - (stop / Point)) < stoplevel) {
      Print("ERROR: Stop must be ", stoplevel, " pips under entry price for BUY orders.");
      return(-1);
    }
    
    if(((target / Point) - (price / Point)) < stoplevel) {
      Print("ERROR: Target must be ", stoplevel, " pips above entry price for BUY orders.");
      return(-1);
    }
  
    if(Ask == price) {
      cmd = OP_BUY;
    } if(Ask > price) {
      cmd = OP_BUYLIMIT;
    } else if(Ask < price) {
      cmd = OP_BUYSTOP;
    }
  } else if(type == "SELL") {
    if(((stop / Point) - (price / Point)) < stoplevel) {
      Print("ERROR: Stop must be ", stoplevel, " pips above entry price for SELL orders.");
      return(-1);
    }
    
    if(((price / Point) - (target / Point)) < stoplevel) {
      Print("ERROR: Target must be ", stoplevel, " pips under entry price for SELL orders.");
      return(-1);
    }
  
    Print("Sell");
    if(Bid == price) {
      cmd = OP_SELL;
    } else if(Bid > price) {
      cmd = OP_SELLSTOP;
    } else if(Bid < price) {
      cmd = OP_SELLLIMIT;
    }
  }
  
  ticket = OrderSend(symbol, cmd, volume, price, 0, stop, target);
  if(ticket < 0) {
    Print("ERROR: Cannot send order: ", ErrorDescription(GetLastError()));
  }
  
  return(ticket);
}

I'm using 4/5 digit broker.

There is something with this TickSize stuff. I'm trying You normalize functions.

 

@WHRoeder: Thanks, NormalizePrice worked :)

Reason: