Strange chart trade markers

 

Ok, so i thought that when your EA places a trade, it is shown on the chart with an opening and closing arrow as long as you specify a color on the ordersend or ordermodify commands (which I did). instead, it shows the opening arrow and two hashes for the TP and SL levels the last time they were changed. It doesn't show a closing arrow when these levels are actually tripped. Is there a toggle switch somewhere that I'm missing?

See the screenshot below. I drew white ovals over the top and bottom red hashmarks i mentioned (they're hard to see). Ignore the horizontal green and red lines, they correspond to a currently open trade.

 

You will need to plot these arrows manually for triggered pending orders, limits and stops. This is annoying and I have solved this problem by re-implementing the routines for plotting these arrows and a bit of code that checks for new trades and plots them:


call plotNewOpenTrades() and plotNewClosedTrades() from common_functions.mqh on every tick and the problem is solved. Additionally you will even get better hint windows when hovering above these arrows that show profit/loss. It is compatible with the automatically created arrows, you wont have duplicate objects on the chart.

 

Fantastic! Thanks a lot. This should help.

 
Here's my routine for plotting TP, SL, indicator levels etc
//+------------------------------------------------------------------+
//| EA equivalent of indicator buffers                               |
//+------------------------------------------------------------------+
/*  Example 1:
 *  if (...) Ordermodify(...);
 *  Polyline("SL"+(oo.ticket%99), oo.SL, Color.Dn, 0);
 *
 *  Example 2:
 *  double  ELineCurr = iMA(NULL,0, ELine.Period, 0, MODE_EMA, PRICE_CLOSE, 1);
 *  Polyline("ELine", ELineCurr, Color.ELine, 1);
 ******************************************************************************/
#define POLYLINE_MAX 20 // Must match priceM
double  price00[], price01[], price02[], price03[], price04[],  // \   Export
        price05[], price06[], price07[], price08[], price09[],  //  \  from
        price10[], price11[], price12[], price13[], price14[],  //  |  Polyline
        price15[], price16[], price17[], price18[], price19[];  //  |
int     LRU[POLYLINE_MAX],  segNo[POLYLINE_MAX];                //   > Import to
string  lineName[POLYLINE_MAX];                                 // _/  PLHelper
datetime mem0[POLYLINE_MAX];
void Polyline(string name, double price, color clr, int shift){
    if (!Show.Objects)  return;
    for (int idx=0; idx < POLYLINE_MAX; idx++){     LRU[idx]++; }
    for (idx=0; idx < POLYLINE_MAX; idx++){
        bool new = lineName[idx] != name;   if (!new) break;    }
    if (new){   idx=ArrayMaximum(LRU);  lineName[idx]=name; segNo[idx]=0;   }
    LRU[idx] = 0;   switch (idx){
    case  0: PLHelper(name, price, clr, idx, new, shift, price00); return;
    case  1: PLHelper(name, price, clr, idx, new, shift, price01); return;
    case  2: PLHelper(name, price, clr, idx, new, shift, price02); return;
    case  3: PLHelper(name, price, clr, idx, new, shift, price03); return;
    case  4: PLHelper(name, price, clr, idx, new, shift, price04); return;
    case  5: PLHelper(name, price, clr, idx, new, shift, price05); return;
    case  6: PLHelper(name, price, clr, idx, new, shift, price06); return;
    case  7: PLHelper(name, price, clr, idx, new, shift, price07); return;
    case  8: PLHelper(name, price, clr, idx, new, shift, price08); return;
    case  9: PLHelper(name, price, clr, idx, new, shift, price09); return;
    case 10: PLHelper(name, price, clr, idx, new, shift, price10); return;
    case 11: PLHelper(name, price, clr, idx, new, shift, price11); return;
    case 12: PLHelper(name, price, clr, idx, new, shift, price12); return;
    case 13: PLHelper(name, price, clr, idx, new, shift, price13); return;
    case 14: PLHelper(name, price, clr, idx, new, shift, price14); return;
    case 15: PLHelper(name, price, clr, idx, new, shift, price15); return;
    case 16: PLHelper(name, price, clr, idx, new, shift, price16); return;
    case 17: PLHelper(name, price, clr, idx, new, shift, price17); return;
    case 18: PLHelper(name, price, clr, idx, new, shift, price18); return;
    case 19: PLHelper(name, price, clr, idx, new, shift, price19); return;
}   }
void PLHelper( string name, double price, color clr, int idx, bool new
             , int shift, double& mem[] ){
    if (new){   ArrayResize(mem, 1);    mem0[idx]=Time[shift];  mem[0]=price;
                                                                    return; }
    int size    = ArraySize(mem);
    if (Time[shift] == mem0[idx]){
        if (size != 1)  mem[0]=price;   // Update new price, else keep initial.
        return; }
    ArraySetAsSeries(mem, true);        // Shift values m[2]=m[1]; m[1]=m[0]
    int firstBar=ArrayResize(mem, size+1)-1;    if (firstBar < 0){      Alert(
        "ArrayResize failed: ",GetLastError());                         return;}
    ArraySetAsSeries(mem, false);
    mem0[idx]=Time[shift];  mem[0]=price;
    if (ObjectMove(name, 1, Time[shift],            price))
        ObjectMove(name, 0, Time[shift+firstBar],   mem[firstBar]);
    else if (!ObjectCreate( name, OBJ_TREND, WINDOW_MAIN,
            Time[shift],            price,
            Time[shift+firstBar],   mem[firstBar] )){                   Alert(
        "ObjectCreate(", name, "Trend) [1] failed: ",GetLastError());   return;}
    else if (!ObjectSet( name, OBJPROP_COLOR, clr ))                    Alert(
        "ObjectSet(", name, "Color) [2] failed: ", GetLastError());
    else if (!ObjectSet( name, OBJPROP_RAY, false ))                    Alert(
        "ObjectSet(", name, "Ray) [1] failed: ", GetLastError());

    double maxError=0;  int maxBar;
    for (int pos=1; pos < firstBar; pos++){
        double error=MathAbs(ObjectGetValueByShift(name, pos+shift)-mem[pos]);
        if (error > maxError){  maxError=error; maxBar=pos; }
    }
    if (maxError >= pips2dbl){  // Split the line into two segments at the max.
        segNo[idx]=(segNo[idx]+1)%1000; string newName=name+"-"+segNo[idx];
        /**/ if (ObjectMove(newName, 0, Time[firstBar+shift], mem[firstBar]))
            ObjectMove(newName, 1, Time[maxBar  +shift], mem[maxBar]);
        else if (!ObjectCreate( newName, OBJ_TREND, WINDOW_MAIN,
            Time[firstBar+shift],   mem[firstBar],
            Time[maxBar  +shift],   mem[maxBar] ))                      Alert(
            "ObjectCreate(", newName, "Trend) [2] failed: ",GetLastError());
        else if (!ObjectSet( newName, OBJPROP_COLOR, clr ))             Alert(
            "ObjectSet(", newName, "Color) [3] failed: ", GetLastError());
        else if (!ObjectSet( newName, OBJPROP_RAY, false ))             Alert(
            "ObjectSet(", newName, "Ray) [2] failed: ", GetLastError());

        ArrayResize(mem, maxBar+1); // Drop firstBar..(maxBar+1)
        if (!ObjectMove(name, 0, Time[maxBar+shift], mem[maxBar]))      Alert(
            "ObjectMove(",name,") [2] failed: ", GetLastError());
    }   // Split the line into two segments at the max.
}   // PLHelper

//++++ These are adjusted for 5 digit brokers.
double  pips2points,    // slippage  3 pips    3=points    30=points
        pips2dbl;       // Stoploss 15 pips    0.0015      0.00150
int     Digits.pips;    // DoubleToStr(dbl/pips2dbl, Digits.pips)
int init(){
    if (Digits == 5 || Digits == 3){    // Adjust for five (5) digit brokers.
                pips2dbl    = Point*10; pips2points = 10;   Digits.pips = 1;
    } else {    pips2dbl    = Point;    pips2points =  1;   Digits.pips = 0; }
    // OrderSend(... Slippage.Pips * pips2points, Bid - StopLossPips * pips2dbl
 
WHRoeder:
Here's my routine for plotting TP, SL, indicator levels etc
Code update https://www.mql5.com/en/forum/130907
 

Thanks. Keep up the good work!