Basic Definitions and Structure

In establishing a re-usable code that will be suitable for use in all strategies to issue orders, determine which orders were executed and to implement logic to control strategy behavior, it will be useful to define and develop several concepts:

  1. Variables are established to hold the price levels corresponding to the four basic order types: BuyLimitValue, SellLimitValue, BuyStopValue and SellStopValue.
  2. These four order types are identified by assigning a unique integer value to each type, maintained in variables: ID_BuyLimit, ID_SellLimit, ID_BuyStop, and ID_SellStop.This facilitates storing information about each order type in arrays. For example, the number of Sell Limit orders executed in the strategy may be stored in element ID_SellLimit of array Orders: Orders[ID_SellLimit].
  3. More sophisticated orders, such as OCO (one cancels the other) or OSO (one send the other) can be implemented in code logic using the four basic orders types above once it is known which orders in these sets have already executed.
  4. Variables are established to hold the price levels corresponding to the four basic order types: BuyLimitValue, SellLimitValue, BuyStopValue and SellStopValue.
  5. The four basic order types may be toggled between active status and inactive status using the variables: BuyLimitOK, SellLimitOK, BuyStopOK and SellStopOK.One could alternatively have used a zero value for BuyLimitValue, SellLimitValue, BuyStopValue or SellStopValuewhenever these orders were “inactive”. However, the toggling the variables BuyLimitOK, SellLimitOK, BuyStopOK andSellStopOK on and off avoids re-calculating order price values when an order is “re-activated” resulting in more efficient code.
  6. Two additional logical variables are defined to specify whether a limit order or stop order will reverse the current position or simply exit the current position: ReverseOnLimitOK and ReverseOnStopOK.
  7. To maximize re-usability of code, the code is segregated into four main blocks. These code blocks provide the following:
    1. Identify which strategy order has just executed. (Function OrderExecuted).
    2. Ensure Complete Position Reversals, if reversing the position is permitted using a stop order (ReverseOnStopOK = true).
    3. Function Logic.StrategyName: Logic that controls the unique behavior of a specific strategy.
    4. Order Generation Engine, placed in the body of the strategy code, determines which orders are valid after analyzing BuyLimitOK, SellLimitOK, BuyStopOK and SellStopOK as well as ReverseOnLimitOK and ReverseOnStopOKAll valid orders are then issued at the appropriate price values: BuyLimitValue, SellLimitValue, BuyStopValue and SellStopValue,

    Items 1, 2 and 4 above are all re-usable in every strategy. Item 3 is unique to specific strategy strategy.

Function OrderExecuted

Method 1: Comparing Price to Limit/Stop Levels

There is no feedback between order execution and a strategy to tell the strategy which of the currently active orders has just executed and resulted in a change in trade position.

One could attempt to determine the order that executed by observing the price of the most recent trade relative to various order limit and stop values.  However, there are numerous problems with this technique both for limit and stop orders, as outlined below:

Limit Orders

When the price touches the limit price, it is not known if the order will be filled. Whether it fills or not will depend upon how many orders are ahead of the user’s order in the queue at the same limit price and what volume is being traded at this price.

Stop Orders

One might think that stop orders would be easier to emulate within code but in fact this task is even more problematic. For example, if the current position is long and there is an active stop loss order at SellStopValue, then it could be reasoned that the stop would execute whenever the following condition was satisfied:

Low  <=  SellStopValue

However, whether such an occurrence triggered the stop would depend upon what Order Entry Preferences the user had set for stop triggers.  The user may set a stop to trigger when any of the following circumstances are satisfied:

Stop Trigger Attributes that Determine when Stop Triggers
Fig 1. Order Entry Preference Options for Stop Trigger
These options are offered in Order Entry Preferences for good reason.  There are situations where the correct selection of a stop trigger will insulate a trader from data problems, such as a single bad tick, or from a single large trade in a thin market.

Knowing if the stop was triggered by an analysis of price relative the stop level is not always possible.  If the trigger preference is based on the bid/ask price or NBBO (National Best Bid/Offer), the strategy does not have this data and therefore cannot determine if the stop was triggered.

Method 2: Analyzing Market Position Changes

Fortunately, it is possible to accurately infer which active order was executed from an analysis of the change in Market Position, and a knowledge of which orders were active and at what price levels.  This method is more complicated but more accurate than attempting to rely on price analysis alone, as used in Method 1.  When the knowledge of which order was executed is required in order to direct the subsequent behavior of the strategy, market position analysis is the only method that will facilitate consist and reliable strategy logic behavior.

The following chart shows how the current Market Position (MP) and the Market Position of the prior tick (MP1) can be analyzed to determine which order was responsible for the position change:

Determine Order Executed by Analyzing Market Position Changes
Fig. 2 Determining Order Executed by Analyzing Market Position Change
(MP = Current Market Position      MP1 = Market Position of Prior Tick)
For this method to work, the strategy Market Position must remain synchronized with the real-world position by formatting Strategy Properties for All to select Adopt the real-world position for the current account”.

The strategy must also be formatted for “Wait for an UROut confirmation before sending a subsequent entry order for the same signal to the market” to avoid having an order transmitted several times while waiting for a fill confirmation.



Initially posted version:  10/02/10

Latest Update:  10/02/10

*.ELD files are compiled for TS 8.8

All ELD and code text files packaged here:

 Users of earlier versions of TradeStation may compile the code
from the text files included in the above *.zip file.

The code may be visualized here:

Function OrderExecuted