Mysterious Stop-Loss calculation issue

 

I'm backtesting an EA I have written and I have the following code for handling stop-loss calculation & setting: 

 

bool subTrailingStop (double dTrailingStop) export
{
    bool   rc           = false;
    bool   op           = false;
    int    iTypeBuySell = OrderType();
    double price        = 0;
    double slAmt        = dTrailingStop * Point;
    double slPrice      = 0;
    string sType        = subOrderTypeToString (iTypeBuySell);

    if (dTrailingStop == 0) {
        return true;
    }

    Print ("SLAmt: ", slAmt);

    double dStopLevel = MarketInfo(Symbol(), MODE_STOPLEVEL);
    if (slAmt < dStopLevel) {
        slAmt = dStopLevel;
    }

    if (iTypeBuySell == OP_BUY) {
        price   = Bid;
        slPrice = price - slAmt;

        if (price > OrderOpenPrice() && OrderStopLoss() < slPrice) {
            rc = OrderModify (OrderTicket(), OrderOpenPrice(), ND(slPrice), OrderTakeProfit(), 0, Green);
            op = true;
        }
    } else if (iTypeBuySell == OP_SELL) {
        price   = Ask;
        slPrice = price + slAmt;
        if (OrderOpenPrice()-price > slAmt && (OrderStopLoss() > slPrice || OrderStopLoss() == 0)) {
            rc = OrderModify (OrderTicket(), OrderOpenPrice(), ND(slPrice), OrderTakeProfit(), 0, Red);
            op = true;
        }
    return rc; 
}

 

When altering a buy order, everything is fine. However, when altering a sell order (say for EURGBP, price being around the 0.755 level), SL is set to 20.755. The odd thing is, the line

Print ("SLAmt: ", slAmt);

 

 prints out 0.001. For reference, ND is defined as follows: 

double ND (double dValue, int iDigits=0) export
{
    if (iDigits == 0) {
        iDigits = Digits;
    }

    return NormalizeDouble (dValue, iDigits);
}


So given the above, I don't see how Stop-Loss could be calculated to 20.755 (again, this only happens for sell orders). I've been staring at this for hours and I guess it must be something totally stupid but I'm just not seeing it. I'd appreciate any pointers as to what I'm doing wrong.

 
  1. Don't paste code
    Play video
    Please edit your post.
    For large amounts of code, attach it.

  2. double slAmt        = dTrailingStop * Point;                     // pips or points * Point. 0.00010
    double dStopLevel = MarketInfo(Symbol(), MODE_STOPLEVEL);        // stop level in points    20
    if (slAmt < dStopLevel) slAmt = dStopLevel;                      // sl amount               20
    price   = Bid;
    slPrice = price - slAmt;                                         // Bid +/- 20
    rc = OrderModify (OrderTicket(), OrderOpenPrice(), ND(slPrice), OrderTakeProfit(), 0, Red);
    Of course it's calculated as 20.755
  3. Do NOT use NormalizeDouble, EVER. For ANY Reason. It's a kludge, don't use it. It's use is always wrong
 
WHRoeder:

  1. Play video
    Please edit your post.
    For large amounts of code, attach it.

  2. Of course it's calculated as 20.755
  3. Do NOT use NormalizeDouble, EVER. For ANY Reason. It's a kludge, don't use it. It's use is always wrong

Thank you for your reply. In reference to your points:

 

1) Fixed, thank you for pointing out the correct way to place code into a post

 

2) I'm not sure I understand. Is the

double slAmt = dTrailingStop * Point;

 not the correct way to scale a pip value to a point representation? Since that is what I'm doing in my code, could you maybe offer an explanation slightly more detailed than just saying "Of course it's calculated as 20.755".

Please don't misunderstand: I appreciate you taking the time to help me (and others) out, but after your replay, I'm genuinely confused about what the correct way of scaling pips to a point value is (and why my code is not working). Following your post and some more research, I've found this link  from one of your posts and changed my code to

    if (Digits == 5 || Digits == 3){    // Adjust for five (5) digit brokers.
        __pips2dbl    = Point*10; 
        __pips2points = 10;   
    } else {
        __pips2dbl    = Point;
        __pips2points = 1;
    }

 but when using the thus calculated __pips2dbl value, SL still is calculated incorrectly.

 On a related question, your code example contained the following construct

int     Digits.pips;    // DoubleToStr(dbl/pips2dbl, Digits.pips)

which however fails to compile for me. What I am doing wrong here?

 

3) Thank you for pointing out the deficiencies of NormalizeDouble. I've read the links you pointed to and have changed my code accordingly. 

 

All in all, thank you for your informative reply, if you could spare a few more minutes for me, I'm sure it would help me a great deal. 

 
  1. double slAmt = dTrailingStop * Point;
    That converts a number of points to a double (a change in price,) not the number of pips to a double. dTrailingStop * _pips2dbl will convert a number of pips to a double.
  2. Since Build 600, dots can't be in variable names. Remove it or rename it.
  3. double dStopLevel = MarketInfo(Symbol(), MODE_STOPLEVEL);        // stop level in points    20
    if (slAmt < dStopLevel) slAmt = dStopLevel;                      // sl amount               20
    You are still comparing a double (change in price) to number of points. Is an Orange < an Apple? The question does not make sense.
 
WHRoeder:
  1. That converts a number of points to a double (a change in price,) not the number of pips to a double. dTrailingStop * _pips2dbl will convert a number of pips to a double.
  2. Since Build 600, dots can't be in variable names. Remove it or rename it.
  3. You are still comparing a double (change in price) to number of points. Is an Orange < an Apple? The question does not make sense.
Thank you, I think I get it now. Appreciate your time & help.