Defining User-Friendly Trend Lines
Classically drawn trend lines provide one of the best indicators for identifying a change or break in a trend. For this reason, their use in directing semi-automated trading strategies is becoming more popular.
Various methods have been proposed to trigger orders by using trend lines manually drawn on the chart. For example, the trend line number or its color can be used to identify the desired order type (Buy Limit, Buy Stop, Sell Limit, Sell Stop).
Desirable characteristics of any system used to define trend lines are that it be logical, intuitive and user-friendly:
However, using trend line numbers to identify the type of order desired is problematic. The trader must draw the desired trend lines in a particular order since trend line numbers are assigned sequentially as they are added to a chart. The trader must ensure that no other trend lines exist on the chart, as previously drawn trend lines may have drifted out view of the range of data displayed on the chart. If a mistake is made and a trend line is deleted and then redrawn, the trend line numbers may no longer match the associated order types and the strategy may not behave as expected.
Using color to identify the desired order type is a bit more user-friendly and less prone to trading errors. After defining the specific colors that are to represent specific types of orders (Buy Limit, Buy Stop, Sell Limit, Sell Stop, etc.), functions such as the built-in Tradestation function TL_FindColor may be used to locate the trend line number of the first trend line matching one of these colors. Unfortunately, the number of colors that display brightly on a chart are limited, and the darker colors are not easily seen.
Using both the trend line Color and Style (solid, dashed, dotted, etc.) to identify the various order types seems to have some advantages:
- Like orders (Buy Limit, Buy Stop) can be assigned the same color but different styles, producing a more user-friendly assignment lending itself to a shorter learning curve and a lower risk for “accidents” from choosing the incorrect color.
- Similarly, orders sharing other similar characteristics (Buy Stop, Sell Stop) can be assigned the same Style (e.g. dotted trend line) but differing colors.
- With multiple styles available, fewer colors need to be used permitting the use of the brightest, most visible colors for trend lines and an intuitive and logical assignment of Color and Style combinations that are easy to remember.
Most all trading strategy actions can be reduced to four order types, Buy Limit, Buy Stop, Sell Limit and Sell Stop, as follows:
Fig. 1. Relation Between Strategy Action and Order Types
To make trend line trading more intuitive and user-friendly, both Color and Style can be used to identify similar characteristics of these four order types, such as the following arrangement:
Fig. 2. Linking Order Type to Trend Line Style and Color
Trend Line Break Out Entry
One often thinks of a breakout trade as a horizontal moving price channel and horizontal stop orders above and below the channel waiting for a breakout in either direction.
However, a more frequent use of the trend line entry is a break in a significant trend. Of course the word significant is relative, but the point is to find a trend that has been continuing for enough bars that so that once the trend breaks the retracement will be sufficient to generate a profit.
CLK09 Crude Oil in an Up Trend – Support Trend Line Drawn
The above chart shows an upward trend in the Crude Oil futures (CLK09) of approximately 2 dollars. This is not a large move for oil, but a retracement large enough to generate a profit is anticipated when this trend is broken.
A Red Dotted trend line has been drawn below the price trend indicating a Sell Stop order is desired. When this trend line is hit, one contract will be sold short.
Short Position Triggered When Prices Crosses Trend Line
CLK09 continues its downward trend for several bars.
After downward trend established, stop loss and profit targets can be added.
As the downward move progresses in the chart below, a Buy Stop (Green Dashed) trend line is added, representing an initial stop loss. A Buy Limit (Green Solid) trend line is added, representing a potential profit target.
Stop Loss Trend Line (Green Dashed) is angled downwards as trend continues.
The downward trend becomes further established. The Buy Stop (Green Dashed) trend line is angled downwards to create a break even stop loss that reflects the downward trend. It is not known whether this trend line or the profit target will be hit first.
Price retraces upwards, triggering the stop loss at $53.
As the price action continues, a minor retracement hits the Buy Stop (Green Dashed) trend line, and the trade is closed out for a small profit of $370.
Copper Futures HGK09 was in a downtrend and then starts moving sideways.
A potential range trading opportunity is anticipated.
A range trade is setup by placing stop loss trend lines above and below the sideways price range. If the price breaks out of this range, the semi-automated trading will stop.
Buy and Sell Trendlines (solid green and red) are added to the price to initiate range trading.
The strategy properties above are adjusted to allow multiple trades in a range trading scenario, by setting the Maximum Trades to a large number (99) and setting the MaxLimitReversals to a similarly large number (99).
The strategy is turned on and starts range trading.
As time progresses, several more range trades occur. Eventually, the price moves higher and triggers the stop loss trend line (green dashed) above the trading range to halt further trading.
Analysis of the strategy performance indicates significant profit from this approach. After subtracting the profit of the first 2 trades ($7,333) which were made on historical bars in setting up the strategy, the net trading profit is $20,000 – $7,333 = $12,666.
The main program is divided into two sections, containing code that must be executed (1) with every tick, and (2) at the end of each bar.
Every Tick Processing Region
- Determine market position.
- Determine when real-time data starts.
- If RealTimeOnly has been specified, identifies when real-time data is available and signals the strategy to start processing trades.
- Determine if there has been a change in position.
- If the position has been changed, process this change using Method ProcessPositionChange.To process position changes, three component methods were created to: (1) determine which order just executed resulting in a position change (Method OrderExecuted), (2) ensure that stop reversal orders complete the position reversal (Method StopReversalCompletion), and (3) adjust strategy logic after any changes in position (Method SetStrategyLogic). These are all described in more detail below.
- Check if the user has moved any active trend line every within the last ReCalcSeconds seconds. If the user changes the position of a trend line while the strategy is running, the new trend line value is calculated by Method TLCalcValue and the new value is reflected in the corresponding strategy generated orders. The slope of the trend line is also recalculated at this time, since the user may have also changed the slope of the trend line as well.
- Submit all orders based on currently active trend lines, using Method ProcessTradeOrders.
Method ProcessPositionChange Components
Determining which order has just executed is more complicated than one would think. When a limit price is hit, there is no guarantee that the limit order will be executed. Similarly, if the stop orders are being forwarded to the Tradestation server, the price hitting the stop price is still not sufficient to determine if the stop order executed because the Order Entry Preferences for stop triggering set by the user are not known by the strategy.
Method OrderExecuted determines which order just executed by comparing the last tick price to the various active order values. The order closest to the last tick price is assumed to be the order that triggered the change in position. This works well for limit and stop orers. Market orders, when the stategy is required to make them, are assume to execute immediately. Therefore the order “that just executed”, contained in variable ID_Order, is hard coded when a market order is issed.
There is a well-documented problem with loss of synchronization of real position with strategy position when stop orders attempt to reverse an existing position.
This occurs because a strategy breaks a reversal order down into two components. For example, when reversing a long position, the strategy will respond to a SellShort Next Bar LimitValue Limit statement by generating two separate orders: (1) Sell Next Bar LimitValue Limit (to close out the long position), and (2) SellShort Next Bar LimitValue Limit.
On historical bars, these two orders execute without problems. However, on real-time bars, the first order is executed, and the second order is generally canceled.
By monitoring the current MarketPosition and identifying the most recent order that executed, one can determine if a desired reversal of position has actually been accomplished.
There are two solutions to ensuring orders to reverse a position using a stop order are completed successfully.
The first solution is to use code to ensure trade reversal occurs, and this is the purpose of Method StopReversalCompletion. If a reversal of position was intended, then variable Reversal will be true. If the position changes from either short or long to a flat position, then the reversal has not been completed. In this case, Method StopReversalCompletion will issue the appropriate market order to complete the reversal.
The second method is accomplished by setting strategy properties as follows:
Format – All Strategies – Automation Tab
- Send strategy generated stop orders directly to the TradeStation Order Execution Network, and
- Always hold stop orders on the TradeStation Order Execution Network’s Stop server, even if the execution destination natively supports stop orders.
If the user does NOT wish to use these Format – All Strategies settings, then the call to the method should be uncommented in the main program.
Method SetStrategyLogic is responsible for enforcing the following trading rules:
- A Buy Stop cannot be “hit” more than once per strategy run. A buy stop order may be used to enter a trade when the price breaks out of a trading channel or when the price breaks out of a downward trend. Such a stop order can only be “hit” one time during a strategy run. This rule is designed to prevent the situation where a second order will be generated if the price action wanders back below this trend line and passes through it a second time from below. It is presumed that the user intended such an order to executed only one time. If the user wants to issue a second BuyStop order after the first trade has closed out, the BuyStop trend line can be moved into its new position, and then the strategy refreshed with Ctl-R. This will restore all valid trend lines on the chart to “active” status for generating new trades.
- A Sell Stop cannot be “hit more than once per strategy run. The rationale is the same as in item (1), except the direction of the trade is opposite.
- A limit order cannot execute more than once per strategy if variable ReverseOnLimitOK = false.If the trader does not intend to reverse his positions, then when a limit order hits it is either to enter a trade or the exit a trade as a profit target. Once this trend line has completed its function (entry or exit), it should not trigger additional trades if the price wanders back down to the trend line. However, when it is desirable to range trade back and forth between two price levels, then ReverseOnLimitOK = true is used. In this case, the limit orders can execute multiple times.
- A Strategy May Not Enter a Second Trade With A Second Stop Order. If any stop trend line is hit occurred during a trade entry, then any remaining stop trend lines remain active for trade exits only. No remaining stop trend lines may be used for a second trade entry. For example, suppose a user sets up two breakout entry orders by bracketing a BuyStop order above the current price and a SellStop order below the current price. The intention of the user is to enter in one direction or the other, but not both directions. Had this order been entered manually, it would be set up as an OCO order (one cancels the other). Rule #3 basically accomplishes the OCO logic in code. Once one side of the bracket order is executed, the other side is not allowed to execute. The code accomplishes this by setting a switch, StopEntryOK, to false once a trade is entered using a stop order. This prevents any further entries using a stop order, effectively canceling the opposite stop order. However, it does permit exiting the trade using the opposite stop order if the price never reaches a profit target and instead reverses direction.
- If an existing position is taken flat rather than reversed by a stop order, then stop all further order processing. When a stop is hit while in a position it serves as a stop loss to exit the trade. Once this type of stop is hit, if the position is taken flat rather than reversed then the strategy should stop immediately and should not generate any further orders. In this case, the strategy label appearing on the chart will turn from yellow to red, warning the user that the strategy is no longer processing orders. If the user intended this stop order to reverse the position by specifying the input parameter MaxStopReversals = 1, then the stop order will reverse the trade and the strategy processing will continue until any other active orders to exit the position have been executed.
- If two stop orders are hit (BuyStop and SellStop) then stop all further trading. If both stops were hit, then one was hit entering the trade, and the other was hit exiting the trade as a stop loss. The second stop hit must be a stop loss and therefore should halt further trading.
- Do not allow more stop order or limit order reversals than permitted by user input parameters MaxLimitReversals and MaxStopReversals.
- Do not generate more trades than allowed by user input parameter MaxTrades.MaxTrades is the number of trades the strategy is allowed to take before it shuts down. This value is compared to TS reserved word TotalTrades before processing any orders in the strategy. Processing continues only if TotalTrades < MaxTrades.In this case, the strategy label appearing on the chart will turn from yellow to red, warning the user that the strategy is no longer processing orders.
End Of Bar Processing Region
End of bar processing includes the following tasks:
- Method StrategyInitialize (executed only once)
- Creates a label variable that will display the input parameters on the chart
- Identifies all valid trend lines, using Method TLValid. A valid trend line is one whose color and style match that of the defined type of order. Since a trend line’s slope does not change during the processing of historical bars, the slope only needs to be determined once for each trend line and is also calculated by Method TLValid. Real-time bars must be handled differently because the user might move one or more trend lines during the execution of the strategy and this may change its slope. Recalculation of the trend line value and the slope is handled in the Every Tick Processing section of the main program, at a frequency determined by the input parameter ReCalcSeconds.
- Tests for duplicate trend lines for the same order type (BuyLimit, BuyStop, SellLimit, SellStop).A trend line previously drawn on the chart may now be outside of the displayed area of the chart and the user may be unaware of its presence. Duplicate trend lines often indicate a user error and the detection of duplicates is needed to ensure the trader does not inadvertently cause the execution of undesired trades.
- Determines the earliest beginning date of any valid trend lines.There is no need for the strategy to generate any orders until the CurrentBar has reached the beginning date and time of the earliest appearing trend line. By identifying this beginning date and time, all bars prior to this date can be bypassed, resulting in greater efficiency.StrategyOK, which toggles the strategy to start processing orders, is set to true when the current bar has reached the beginning date and time of the earliest appearing trend line.
- Sets the strategy position to any existing position specified in the input parameter SetStrategyPosition.Although setting the formatting parameter “Adopt real-world position for current account” will also accomplish this synchronization, it does not do so until just before the real-time bars start to occur. Therefore, the strategy does not have knowledge of the historical position from the bar where the historical position was placed all the way up to the first real-time bar.By setting the historical strategy position far back at the beginning of the chart, the strategy is aware of this position during all historical bars and will trade correctly on historical bars as well as the real-time bars for all valid trend lines drawn.
- Determine which trend lines are active, using Method TLActive.A trend line is considered active when the current bar has reached the beginning date and time for this trend line. At this point, the order variable associated with this trend line (BuyLimitOK, BuyStopOK, SellLimitOK or SellStopOK) is set to true. Similarly, if a trend line is hit, then after the associated order has been generated, the trend line is deactivated. This avoids the processing of any trend line before its beginning date and time, or after it has served its purpose, allowing the strategy to run faster.
- Calculate the next bar value and slope of each active trend line, using Method TLCalcNextBarValue.
- Re-display the strategy chart label information on the chart, so the user can see the important input parameters in force, and can also determine if the strategy is still active or not.
The method used to calculate the trend line value varies depending upon whether the calculation is being done at the end of a bar or intrabar.
- Intrabar Trend Line Values. The value of the trend line at the current bar is used to generate intrabar orders. The value of the trend line is sampled every ReCalcSeconds (default value = 2). This ensures that if the user moves the trend line during the strategy, the new values will be updated in the strategy generated orders in no more than ReCalcSeconds.
- End of Bar Trend Line Values. The values of all active trend lines at the next bar are calculated by adding the current trend line value and it’s slope (the amount it changes with each bar), storing the result in variables BuyLimitValue, BuyStopValue, SellLimitValue and SellStopvalue. This is to ensure that on the next tick following the end of bar tick, the value of the trend line for the next bar will be used on the first tick of the new bar. The trend line values at the next bar are used, rather than at the current bar since orders are written for the next bar during the current bar, using the syntax:
[Buy/Sell] next bar at ‘value’ [Limit/Stop]
Therefore, the next “tick” after the end of bar will be the next bar.
This method generates all of the orders implied by all active trend lines the user has drawn.
The processing of these orders depends upon the current market position, MP. For example, if the current position is flat, then only potential entry orders are processed. If, on the other hand, the market position is long then only long exit (LX) orders are generated. Similarly, if the market position is short then only short exit (SX) orders are generated.
A Switch MP begin statement branches to the orders that are appropriate to the current market position. Then, the various order types of orders are checked to determine if they are still active by inspecting the variables BuyLimitOK, BuyStopOK, SellLimitOK and SellStopOK. Only those orders still active are then placed by the strategy.
Debugging statements are dispersed throughout the code and generate a log of all orders placed if the user has set the strategy formatting option Debugging = true. This log may be examined using the EasyLanguage Output Bar.
The possibility exists for not only exiting a position but also reversing a position if the input parameters are set appropriately. This is required when automated range trading is desired.
Your content goes here. Edit or remove this text inline or in the module Content settings. You can also style every aspect of this content in the module Design settings and even apply custom CSS to this text in the module Advanced settings.
Trend Line Alerts
To prepare for using this trend line strategy system, the trend line Properties default values are set as follows:
The default color (cyan) trend lines may be used by the user to generate alerts about potential trades without triggering the trade order to be generated. This is useful to alert the user to potential trades where the price action has not developed fully enough for the trade order to be formulated.
The trend line default properties for Alerts are set as follows:
When using trend line trading with strategies, many trend lines will be drawn. For convenience, the Toolbar at the top of the Chart workspace can be customized to include a Draw Trend Line icon (pencil icon in the lower right):
This trend line drawing tool speeds up the process of drawing multiple trend lines. The default color is set to a Color and Style combination other than one of those chosen for the four main order types, to avoid inadvertently triggering orders when a “trial” trend line is being placed.
Once the trend line is in position, the Color and Style of the trend line is changed to that associated with desired order type, as noted in the above table. If the trader prefers a different Color and Style association between the various order types, these can be re-defined in the input variables of the strategy.
If a trader wants only an alert and does not wish to place a trade order then the default (Cyan – Solid Line) trend line is used to trigger the alert. If a trade execution is desired, then the trend line drawn is immediately reformatted to the Color and Style appropriate for the desired order type.
Format Strategy Properties
Several user-defined input variables to the TL_Trader strategy determine which orders are possible and therefore generated.
RTOnly (Real-time only): If False, trading may occur on historical and real-time bars. If True, trading only may occur on real-time bars.
SetStrategyPosition: Sets the number of contracts (shares) of any real positions prior to starting the strategy.
TradeSize: Number of contracts (shares) for each trade.
PriceRef: The price used to trigger stop orders. Note, with IOG = true, the most recently traded price is always equal to “close”. In contrast, with IOG = false, close will be the actual closing price of the bar and trades will not be triggered until the last tick of the current bar.
TradeDirection: = 0 if trades may occur in either direction, = 1 if only long trades are permitted, and -1 if only short trades are permitted.
MaximumTrades: The maximum number of trades the strategy can make before becoming inactive.
MaxLimitReversals: The number of times a limit order may reverse the current position. If a limit order is being used as a profit target to close a position then set = 0. If a limit order is being used to reverse the current position when hit, then set a value > 0. If range trading back and forth between two limit orders, then set some high value to allow multiple reversals of position.
ReCalcSeconds: The number of elapsed seconds before the strategy will check to see if the user has moved or deleted any of the established trend lines. If a trend is moved by the user, this will be the number of seconds that will elapse before the new order price is calculated based on the trend line’s new position.
Debug: If true, a log of all orders generated is printed in the EasyLanguage Print Log.
UseKillColor: Once a limit order is “hit”, it usually deactivated from further use, depending on the settings of MaximumLimitReversals. Each stop order that is “hit” during the strategy is also deactivated. When a trend line is deactivated, it is set to color = KillColor if UseKillColor = true.
This is to give the user a visual confirmation that the order associated with a trend line has been executed and become inactive. It also reminds the user that if this trend line is moved to a new position, it remains inactive until its color and style has been changed back to one of the combinations that indicates a BuyLimit, SellLimit, BuyStop or SellStop order, and the strategy is refreshed with Ctl-R.
KillColor (default white): A trend line that is deactivated during the running of the strategy is changed to color = KillColor if UseKillColor = True.
TLTrader Strategy Automation Calculation Settings
Recommended Automation formatting settings are shown above.
Strategy Properties for All Strategies
Recommended formatting options under Strategy Properties for All Strategies, under the Automation tab, are shown below. The stop order selections are required for the strategy to perform position reversals during real-time data.
Strategy Properties for All Strategies
The following procedure is recommended when using this strategy:
- Insert the strategy on a chart.
- Format the strategy input parameters for the style of trading desired.
- Draw one or more trend lines to control order generation. The default color for a newly drawn trend line will usually be a color other than the Red or Green which the strategy recognizes as an order generating trend line.
- Format each trend line to the color (red, green) and style (solid, dotted) associated with the type of order this trend line will generate.
- Once all trend lines have been defined and are in the appropriate positions on the chart, refresh the chart using CTL-R or from the Menu bar using: View – Refresh – Reload.
No trend line that the user draws is recognized by the strategy until the chart has been refreshed.
This is to prevent the strategy from generating an order before the user has determined the type of order to be generated by the color and style of the trend line, and positioned the trend line to the exact position desired. If a new trend line is added to the chart while the strategy is active, this new trend line will not be recognized by the strategy until the chart is again refreshed using CTL-R or from the Menu bar using: View – Refresh – Reload.
- Once a trend line is recognized by the strategy it will start generating orders. These orders can be viewed in the TradeManager selecting the tab Strategy Orders.
- Once the strategy is confirmed to be generating the correct orders, you can take format the strategy to: “Automate executing using [account #]” with confirmation “On/Off”. From this point, all orders shown in the Trademanager Strategy Orders tab will be sent to the Tradestation server for execution.
Initial posted version: 4/24/09
Latest Update: 10/08/21
*.ELD files are compiled for TS 9.5
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: