Announcement

Collapse
No announcement yet.

Avoiding duplicate orders

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Avoiding duplicate orders

    Hi,

    I'm trying to find the best way to get the order status to be clean before issuing another order. In other words, how can I quickly check that there is no order currently either WORKING, PLACING, CANCELING, PARTIALFILL, UPDATING? I don't care if there was a previous order that was FILLED, REJECTED or CANCELLED. I just want to avoid issing a new order if one of the conditions in the first list of conditions is not present. Please give an example code line. I think it'd be tremendously helpful if there was a call like, Trade.isOrderInProcess(symbol) that will return true is one of the conditions in the first list is true.

    Thanks,

    _esigtrader

  • #2
    Adding more details

    Hi all,

    I'm checking for any open un-filled orders as follows -

    debugPrintln("CHECKING FOR OPEN ORDERS");
    var openOrders = Trade.getOrders({states:Order.STATE_WORKING
    | Order.STATE_PLACING
    | Order.STATE_CANCELING
    | Order.STATE_PARTIALFILL
    | Order.STATE_UPDATING});
    if(openOrders != null) {
    for(var i=0, len=openOrders.length; i<len; i++){
    debugPrintln("Open Order " + i + " = " + Order.state(openOrders[i]));
    }
    return;
    } else {
    debugPrintln("NO OPEN ORDERS - CHECKING FOR POSITION");
    var curPosition = Trade.getPosition();
    if(curPosition != null && Position.isFlat(curPosition)) {
    //THE POSITION SHOULDN'T BE FLAT AFTER AN ORDER IS FILLED.
    debugPrintln("NO OPEN ORDERS AND POSITION IS FLAT");

    }
    }

    In the above code, I'm getting a flat position even if I have open position. This results in code opening another order, thinking that the conditions are met to issue another order and an order hasn't been issued yet.

    Note that, I'm issuing the buy/sell order in the previous tick and checking for open orders (the above code) in the following ticks.

    Any ideas on how I can resolve this?

    Thanks,

    _esigtrader

    Originally posted by esigtrader View Post
    Hi,

    I'm trying to find the best way to get the order status to be clean before issuing another order. In other words, how can I quickly check that there is no order currently either WORKING, PLACING, CANCELING, PARTIALFILL, UPDATING? I don't care if there was a previous order that was FILLED, REJECTED or CANCELLED. I just want to avoid issing a new order if one of the conditions in the first list of conditions is not present. Please give an example code line. I think it'd be tremendously helpful if there was a call like, Trade.isOrderInProcess(symbol) that will return true is one of the conditions in the first list is true.

    Thanks,

    _esigtrader

    Comment


    • #3
      Bugelay of few ticks between Order fill and Position status

      Posting this as a bug.

      Originally posted by esigtrader View Post
      Hi all,

      I'm checking for any open un-filled orders as follows -

      debugPrintln("CHECKING FOR OPEN ORDERS");
      var openOrders = Trade.getOrders({states:Order.STATE_WORKING
      | Order.STATE_PLACING
      | Order.STATE_CANCELING
      | Order.STATE_PARTIALFILL
      | Order.STATE_UPDATING});
      if(openOrders != null) {
      for(var i=0, len=openOrders.length; i<len; i++){
      debugPrintln("Open Order " + i + " = " + Order.state(openOrders[i]));
      }
      return;
      } else {
      debugPrintln("NO OPEN ORDERS - CHECKING FOR POSITION");
      var curPosition = Trade.getPosition();
      if(curPosition != null && Position.isFlat(curPosition)) {
      //THE POSITION SHOULDN'T BE FLAT AFTER AN ORDER IS FILLED.
      debugPrintln("NO OPEN ORDERS AND POSITION IS FLAT");

      }
      }

      In the above code, I'm getting a flat position even if I have open position. This results in code opening another order, thinking that the conditions are met to issue another order and an order hasn't been issued yet.

      Note that, I'm issuing the buy/sell order in the previous tick and checking for open orders (the above code) in the following ticks.

      Any ideas on how I can resolve this?

      Thanks,

      _esigtrader

      Comment


      • #4
        Many times, I also have witnessed a delay of a few seconds from the time of a fill to the position getting updated. I use the following command to get a position.

        position = Trade.getPosition( { "symbol": getSymbol(), "account": acct, "connectionID": dcid } );

        However, knowing this position may be a few seconds stale, I check for orders which got filled and record a timestamp. After some number of seconds have passed, then I assume the position is likely to be reliable.

        Having seen instances of lengthy delays in EFS updating the position, and sometimes delays in showing the latest order status, I added another process which looks at the executions (fills) generated by the broker's app. (In my case, I use the executions.txt file generated by IB TWS.) Using a script external to eSignal, I tabulate the broker's position and output to a file so that EFS can check that position. The position derived from broker data always seems to be accurate and timely. You can brainstorm other ways to go about deriving a position from a source other than EFS, but I strongly recommend not to rely solely on EFS for position info.


        In reference to checking for the status of all orders, I use the getOrders method for one state at a time. This has worked well for me. I do not try to combine multiple states in one command.

        Example:

        working = Trade.getOrders( { "states": Order.STATE_WORKING, "symbol": tkr, "account": acct, "connectionID": dcid } );

        Comment


        • #5
          Awesome response Omerproteus! Thanks! I am glad that I'm not the only one using EFSAT. I wish the eSignal support was more responsive on these matters - lack of which is obviously concerning and would prevent me from using it on a live account. Are you using it live trading? I'm curious why you don't use IB directly to write your algo? I don't; because, I haven't had a chance to look at it yet.

          In any case I've overcome the position delay issue using my internal state machine that keeps track of pending and completed orders and so far it seems be working well. I can share more if you'd like.

          I've also found a couple of other rather serious glitches in eSignal - namely,

          1. Every once in a while the Trade.buy... commands go completely ignored by the system and nothing happens. This obviously screws up my internal logic that assumes that I'm in impending long position. Haven't seen this for sell yet, but would expect it to happen at some point.

          2. Using MMP/MMS on eSignal is very risky! I've sent an email to [email protected] about this with a screenshot - but the problem in a nutshell is that the stop-loss and profit targets are triggered only for the first fill response from IB. In other words, if the strategy calls for 5 contracts as the amount, but the order is filled by the broker in two separate partials (let's say 3 and 2) - then the profit and stop-loss will be triggered by MMS only for the first 3 contracts - ignoring the second fill!! This will leave you at huge risk as you'll have to manually or in your code, close out on the remaining 2 contracts.

          Thanks,

          _K

          Originally posted by omerproteus View Post
          Many times, I also have witnessed a delay of a few seconds from the time of a fill to the position getting updated. I use the following command to get a position.

          position = Trade.getPosition( { "symbol": getSymbol(), "account": acct, "connectionID": dcid } );

          However, knowing this position may be a few seconds stale, I check for orders which got filled and record a timestamp. After some number of seconds have passed, then I assume the position is likely to be reliable.

          Having seen instances of lengthy delays in EFS updating the position, and sometimes delays in showing the latest order status, I added another process which looks at the executions (fills) generated by the broker's app. (In my case, I use the executions.txt file generated by IB TWS.) Using a script external to eSignal, I tabulate the broker's position and output to a file so that EFS can check that position. The position derived from broker data always seems to be accurate and timely. You can brainstorm other ways to go about deriving a position from a source other than EFS, but I strongly recommend not to rely solely on EFS for position info.


          In reference to checking for the status of all orders, I use the getOrders method for one state at a time. This has worked well for me. I do not try to combine multiple states in one command.

          Example:

          working = Trade.getOrders( { "states": Order.STATE_WORKING, "symbol": tkr, "account": acct, "connectionID": dcid } );

          Comment


          • #6
            To eliminate order duplications with no need of reading of positions or orders via
            Trade.getOrders or Trade.getPositon() you could use the following technique:

            Keep track of Order id's.
            Use OrderId as a flag.
            When it is null, you have no active order.
            When it is not null your order is working

            order placement:

            if (OrderId == null) // we do not have active/working order so we can safely place a new order
            OrderId = Trade.BuyMarket......

            To reset Order Id
            you need to add in built function
            which is called by EFS-AT execution engine
            when position changes.

            function onPositionUpdate(positionID)
            {
            if (Connection.isConnected()
            && Position.connection(positionID) == Trade.getCurrentConnectionID()
            && Position.symbol(positionID) == getSymbol()
            && Position.account(positionID) == Trade.getCurrentAccount())
            {

            if (OrderId != null && Order.state(OrderId) == Order.STATE_FILLED)
            OrderId = null; // resets order id to allow placement of new order


            ....

            This is reliable;
            works well;

            Comment


            • #7
              Hi Omerproteus,

              I am wondering if you are using

              OnPositionUpdate() and
              OnExecutionUpdate()

              in your code?

              If you are using the Trade.getPosition( ...); or Trade.getOrders (...) and
              calling them from with your function main (or a function called from main)
              you maybe introducing a bit of delay yourself - as you need a new tick ...

              when checking status of individual order (and knowing OrderId) instead of launching order scan using getOrders
              Trade.getOrders( { "states": Order.STATE_WORKING, "symbol": tkr, "account": acct, "connectionID": dcid } );
              I would suggest to use the following
              if (Order.state(OrderId) == Order.STATE_WORKING)
              which does not need to scan trough list of orders

              I agree with you that order management engine has a lot of delays which are causing problems.

              I find position status reliable if manage it via OnPositionUpdate.
              I keep order numbers myself and raraely scan trough list of positions or orders.

              My main problem is with order cancelations or modifications (stop amendment).
              I always check order status before cancellations or amendments , but that still sometimes fails, and stops EFS-AT execution catastrophically.
              if (Order.state(OrderId) == Order.STATE_WORKING)
              Trade.CancelOrder(OrderId);<- will often fail as state may have changed before status check and order placement

              Comment


              • #8
                I have used some of your code to check my orders. However, when I try to execute this code:

                if(currentWorkingOrder == null &&
                low(0,inv(1)) > i5sma48_1) {Trade.buyLimit(i5sma48_1 * .90);
                currentPlacingOrder = Trade.getOrders({"states": Order.STATE_PLACING, "symbol": getSymbol(), "account": account, "connectionID": connection});
                currentWorkingOrder = Trade.getOrders({"states": Order.STATE_WORKING, "symbol": getSymbol(), "account": account, "connectionID": connection});
                }

                eSignal will rip off more than 1 order. I have even used:

                currentPlacingOrder = Trade.buyLimit(i5sma48_1 * .90);
                currentWorkingOrder = Trade.buyLimit(i5sma48_1 * .90);

                As flags to stop the orders from firing off. But that is of no help.

                I have even input a "sleep" function for 2 minutes. And have started toying with for and while loops to wait for the Order.STATE to come back. Both have failed thus far.

                Any suggestions to slow the orders from firing?

                Gracias

                Comment


                • #9
                  Please refer to my post wich is before yours
                  You need to reset your cutrentworkingorder to null in in
                  Onpositionupdate

                  You do not need to have two variables for placing orders
                  You actually do place two orders in your code
                  Use only
                  If (cutrentworkingorder == null && your entry criteria)
                  cutrentworkingorder = trade.buylimit ....

                  Comment


                  • #10
                    AdanS01,

                    It took me some time to consider how to integrate OnExecutionUpdate into my scripts. Now I have done some major code revisions, OnExecutionUpdate has been useful for updating state variables, which in turn prompt main() to query the Executions object for new fills. Using the Execution object gives accurate and timely information, specifically when trading at IB. I simply compute the current position by aggregating the quantities of past fills (Execution ID's).

                    OnPositionUpdate might be even better, but I had a specific need to track individual executions. In any case, using the callback function is much better than waiting for the next tick to trigger main(). OnPositionUpdate might be useful in collecting another source of position size, to reconcile against the position which I compute from the Execution object.

                    Finally, I did try using OnOrderUpdate, but it was being called frequently enough that at some moments, my program stalled or crashed. There was little need for it, and perhaps the callback code was taking longer than the typical window of time between chart ticks.

                    Comment


                    • #11
                      Thanks, its a great news to see that OnExecutionUpdate gives god info with IB

                      Comment


                      • #12
                        Fellas, thanks again for all your help. I am wondering, should I be making this nested IF statement into a callback? This code has finally stopped multiple orders on the same side.

                        Gracias

                        if(openOrders != null) {
                        for(var o=0, len=openOrders.length; o<len; o++){
                        if(Order.symbol(openOrders[o]) == sSymbol){
                        if(Order.isBuy(openOrders[o]) == true){orderIsBuy = true;}else{orderIsBuy = false};
                        };
                        };
                        };

                        Comment

                        Working...
                        X