Managing different trailing stop values for different trades

 

Is there any way I can store a trailing stop value that can be matched with certain trades.


One way I was thinking was to store the ticket number into an array when the trade is opened and then store the stop loss value into that part of the array eg...


ticket=OrderSend(Symbol(),OP_SELLSTOP,selllots , sellentry, 3, sellstop, selltpx3,"Trailing Stop Trade",Mnumber3);  //Open Sell Pending Order

trailingstopvalue[ticket] = 40;

then in future when I use orderselect...


OrderSelect(count, SELECT_BY_POS);
if (trailingstopvalue[OrderTicket()]....) {code to modify stop to that ticket number using the trailing stop value in  trailingstopvalue["Ticket Number"]  }


First question is can an array handle numbers that high?


Second problem is the order starts off as a pending order. When It gets triggered into a Buy or Sell order does the ticket number change?


Thanks - Dale

 
dazamate:
Is there any way I can store a trailing stop value that can be matched with certain trades.
One way I was thinking was to store the ticket number into an array when the trade is opened and then store the stop loss value into that part of the array eg...

First question is can an array handle numbers that high?
Second problem is the order starts off as a pending order. When It gets triggered into a Buy or Sell order does the ticket number change?
  1. Second question, ticket number does not change. Only changes on a partial close.
  2. No it can't. 32 bit application/4 bytes per entry would be a max of 500 million. But you don't need to. You can only open 1000 order max (IBFX, other brokers maybe less.)
    #define MAXTRADES 1000
    int tickets[MAXTRADES]; double trailingStopValue[MAXTRADES]; ...
    int start(){
        for (iT=0; iT < MAXTRADES; it++) if (tickets[iT] != 0){ 
            // Remove closed orders from arrays
            if (!OrderSelect(tickets[iT],SELECT_BY_TICKET)) tickets[iT] = 0; // Closed
            else{
                if (trailingstopvalue[iT]...) ...
            }
        }
        :
        ticket=OrderSend(Symbol(),...);
        if (ticket < 0) Alert("OrderSend Failed ", GetLastError());
        else    for (iT=0; iT < MAXTRADES; it++) if (tickets[iT] == 0){ 
            ticket[iT] = ticket;    
            trailingStopValue[iT] == ...;
            break;
        }
    :

The only problem with this approach is if the terminal restarts, OS crash, power glitch, you loose the content of your arrays. EA's must be coded to recover.

  1. Persistent storage. You must write out the arrays to a file each time you update them and read back in on startup.
  2. What is trailingStopValue? Can you calculate it. Use a range of magic numbers to differenciate the different trade types.
 

WHRoeder


Thankyou for the reply.

I got a feeling you may have misunderstood what I was trying to do.


Each time I open a trade, on the spot I want to calculate the appropriate trailing stop value, and have that referenced with the ticket I just created.

So when I do ...

ticket= OrderSend(Symbol(),OP_BUYSTOP,buylots, buyentry, 3, buystop, buytpx3, "TURTLEB", Mnumber3)

then I want to link a trailing stop value to that ticket number

so something like

ticket= OrderSend(Symbol(),OP_BUYSTOP,buylots, buyentry, 3, buystop, buytpx3, "TURTLEB", Mnumber3)

trailingstopvalue[ticket] = (trailing stop calculation);

so then when I scan my open orders I can match the ticket numbers up with that part of the array and I will get the trailing stop loss value for that particular order.

but when you open a new ticket the ticket number might be "25855187" and the questions was can you make arrays handle values you like eg... trailingstopvalue[25855187] will have the trailing stop value stored in in that section of the array for that tick number.

I understand what you're saying how these values need to be stored in case the EA gets cut off... Not sure how you are doing that in the code above. Still learning far from an expert with coding.

What does your code do there? I can't see how it matches ticket numbers with specific values I want for trailing stops. But hopefully this post clears up everything. Thanks WHRoeder, you're a gun at this stuff.







 
  1. dazamate:
    so then when I scan my open orders I can match the ticket numbers up with that part of the array and I will get the trailing stop loss value for that particular order.
    Unnecessary.
    for(int iPos = OrdersTotal()-1; iPos >= 0 ; iPos--) if (
        OrderSelect(iPos, SELECT_BY_POS)                    // Only my orders w/
    &&  OrderMagicNumber()  == magic.number                 // my magic number
    &&  OrderSymbol()       == symbolChart                                  // and my pair.
    ){
       Print("Order #",OrderTicket()," has a stopLoss value of ",PriceToStr( OrderStopLoss() ));
    }
    :
    string  PriceToStr(double p){ return( DoubleToStr(p, Digits) ); }
  2. I understand what you're saying how these values need to be stored in case the EA gets cut off... Not sure how you are doing that in the code above. Still learning far from an expert with coding.

    I'm not. I'm not going to code everything for you.
  3. What does your code do there? I can't see how it matches ticket numbers with specific values I want for trailing stops.
    Then you need to learn to code because that is exactly what it does.
 
dazamate:

ticket= OrderSend(Symbol(),OP_BUYSTOP,buylots, buyentry, 3, buystop, buytpx3, "TURTLEB", Mnumber3)

trailingstopvalue[ticket] = (trailing stop calculation);

The MQL4 language doesn't have the sort of built-in feature which you're trying to use here. You are going to have to implement it more manually yourself, by using a list of ticket numbers and their associated t/s, and manually looking up and storing the t/s for a given ticket. For example, you could use a pair of arrays, one containing the ticket numbers and one containing the t/s, or a single array with two dimensions. This is simply a variant on the sort of thing which WHRoeder has already suggested:

// Global variables holding a list of ticket numbers and the associated t/s value...
double TrailingStopList[][2];
int TrailingStopTickets = 0;

// ...When a ticket has been created, add it to the index
TrailingStopTickets++;
ArrayResize(TrailingStopList, TrailingStopTickets);
TrailingStopList[TrailingStopTickets - 1][0] = OrderTicket();
TrailingStopList[TrailingStopTickets - 1][1] = << trailing stop value >>;

// ...When you need to look up the trailing stop for a ticket
double GetTrailingStop(int ForTicket)
{
  for (int i = 0; i < TrailingStopTickets; i++) {
    if (TrailingStopTickets[i][0] == Ticket) return (TrailingStopTickets[i][1]);
  }
  // WTF? No trailing stop recorded for this ticket
  return (0);
}

You will also obviously need to remove entries from your index when tickets have ceased to exist.

The further issue this raises, and which WHRoeder is referring to, is what happens if MT4 gets restarted. You need to do something like storing your index on disk before the EA terminates, and re-reading it from disk when the EA is reloaded. (This is a relatively unusual problem in MT4 because most systems only use the trade information in the MT4 order history, which is downloaded from the broker, and don't need or store any extra local information about each ticket.)

You only need to do any of this if you can't, from the order details at any given point in time, re-calculate what the t/s value should be. If it is possible to re-calculate a t/s at any time given the current order details, then it would be preferable to do that rather than incurring the complexity of storing the information and having to re-load it from disk - with attendant problems in disaster scenarios such as the hard disk failing.

 

Hey there thanks again for your replies guys.

I actually was losing sleep over this problem and I did think up the 2 dimensional array option then I seen your post this morning jjc. Sorry WHRoeder I don't expect you to write the code out for me. I just thought somehow you were storing the array values to a file with your example and I couldn't work out how you were doing it. But I have given it much thought and have just decided to go with the universal trailing stop value instead of calculating special trailing stops for each ticket. Although it is good to know how one would do it if a similar situation did arise.

I bookmarked that link with all the learning material WHRoeder . With the intelligent code you guys come up with, you's must have an EA sitting there making you millions am I right :P. Thanks guys!

Reason: