TRADERS’ TIPS
For this month’s Traders’ Tips, the focus is Ken Calhoun’s article in this issue, “Trading Gap Reversals”. Here, we present the April 2016 Traders’ Tips code with possible implementations in various software.
The Traders’ Tips section is provided to help the reader implement a selected technique from an article in this issue or another recent issue. The entries here are contributed by software developers or programmers for software that is capable of customization.
In the article “Trading Gap Reversals” in this issue, author Ken Calhoun presents an intraday trading strategy for trading gap reversals in stocks that have a major gap down and then start to fill the gap during the first hour of the trading day.
We have provided the TradeStation EasyLanguage code for a strategy based on the rules described by the author. One of the challenges a trader may find is locating trading candidates each day that meet the author’s setup criteria. To help with this, you can use the built-in TradeStation Hot Lists application. One approach could be to set the Hot List application to return Gap Down % to a list of symbols with the largest percentage gaps (Figure 1).
FIGURE 1: TRADESTATION. Here is an example TradeStation Hot List application and strategy applied to a one-minute chart of SolarCity Corporation.
To download the EasyLanguage code, please visit our TradeStation and EasyLanguage support forum. The code for this article can be found here: https://community.tradestation.com/Discussions/Topic.aspx?Topic_ID=142776. The ELD filename is “TASC_APR2016.ELD.”
For more information about EasyLanguage in general, please see https://www.tradestation.com/EL-FAQ.
[intrabarordergeneration = true] inputs: MinGapPercent( 10 ), BreakoutAmtAboveLow( .50 ), TrailAmount( .40 ), LastEntryTime( 1030 ) ; variables: intrabarpersist PriorBarStatus( 0 ), CurrentBarStatus( 0 ), intrabarpersist GapOK( false ), TimeOK( false ), LowestLow( 0 ), TT( 0 ), MP( 0 ), intrabarpersist NumTrades( 0 ) ; once begin SetStopShare ; end ; TimeOK = Time <= LastEntryTime ; CurrentBarStatus = BarStatus( DataNum + 1 ) ; TT = TotalTrades ; MP = MarketPosition ; // First Tick of the New Day if PriorBarStatus <> CurrentBarStatus and Date <> Date[1] then begin GapOK = Open <= Close[1] * ( 1 - MinGapPercent * .01 ) ; NumTrades = TT[1] ; end ; if Date <> Date[1] then LowestLow = Low else LowestLow = MinList( Low, LowestLow ) ; if GapOK and TimeOK and NumTrades = TT and MP = 0 then Buy next bar at LowestLow + BreakoutAmtAboveLow Stop ; SetDollarTrailing( TrailAmount ) ; PriorBarStatus = CurrentBarStatus ;
This article is for informational purposes. No type of trading or investment recommendation, advice, or strategy is being made, given, or in any manner provided by TradeStation Securities or its affiliates.
Ken Calhoun’s trading gap reversals strategy described in his article in this issue can be easily applied in TC2000 version 16 using EasyScan and the new simulating trading features.
We scanned the Russell 3000 to find stocks between $20 and $70 that gapped down at least 10% at market open. The scan turned up INCY, MYL, NILE, and PPC. We then placed buy-stop orders 50 cents above the low on each stock. At the same time, we placed profit target and stop-loss orders 5% above and below the entry price. These orders were tied to the buy-stop order and paused until the buy was executed. Once the buy order was filled, they became active orders.
Out of the four simulated trades, two produced a profit and two were losses: INCY +5.9%, PPC +5%, NILE -4.8%, and MYL -3.8% (Figure 2).
FIGURE 2: TC2000. Chart of INCY showing the one-minute time frame. The buy-stop order was filled at $58.76, which triggered the sell-stop and sell-limit (profit target) orders.
You can try the simulated trading yourself at www.TC2000.com.
Ken Calhoun’s article in this issue, “Trading Gap Reversals”, presents a strategy to take advantage of large gap downs. The system was designed to be run on intraday data so it will not work on the Daily Chart version of MetaStock.
Shown here are formulas for an exploration to find these trading opportunities. This should be run shortly after the market opens. It will require data from the two prior days for the calculations to work correctly, so it is recommended to use either five- or 10-minute data. Be sure to set the exploration to load at least 250 records.
Column A Column Name: Close formula: {current close} C Column B Column Name: Open formula: {Open of the current day} new:= ROC(DayOfWeek(),1,$)<>0; ValueWhen(1, new, O ) Column C Column Name: Prev C formula: {Close of the previous day} new:= ROC(DayOfWeek(),1,$)<>0; ValueWhen(1, new, Ref(C, -1) ) Column D Column Name: range formula: {High - Low range of previous day} new:= ROC(DayOfWeek(),1,$)<>0; HighestSince(1, new, H)-LowestSince(1, new, L) Column E Column Name: target formula: {target entry price} new:= ROC(DayOfWeek(),1,$)<>0; ValueWhen(1, new, O + 0.50 )
new:= ROC(DayOfWeek(),1,$)<>0; r:= HighestSince(1, new, H)-LowestSince(1, new, L); C >= 20 AND C <= 70 AND ValueWhen(1, new, Ref(r >= 1, -1)) AND ValueWhen(1, new, (Ref(C, -1) - O) > (Ref(C, -1)/10))
For this month’s Traders’ Tip, we’ve provided the study “Gap reversal.efs” based on the formula described in Ken Calhoun’s article in this issue, “Trading Gap Reversals”. The author presents an intraday trading strategy based on buying gap-down reversals.
The study contains formula parameters that may be configured through the edit chart window (right-click on the chart and select “edit chart”). A sample chart is shown in Figure 3.
FIGURE 3: eSIGNAL. Here is an example of the study plotted on a one-minute chart of FTNT.
To discuss this study or download a complete copy of the formula code, please visit the EFS Library Discussion Board forum under the forums link from the support menu at www.esignal.com or visit our EFS KnowledgeBase at https://www.esignal.com/support/kb/efs/. The eSignal formula script (EFS) is also available for copying & pasting here:
/********************************* Provided By: eSignal (Copyright c eSignal), a division of Interactive Data Corporation. 2016. All rights reserved. This sample eSignal Formula Script (EFS) is for educational purposes only and may be modified and saved under a new file name. eSignal is not responsible for the functionality once modified. eSignal reserves the right to modify and overwrite this EFS file with each new release. Description: Gap Reversals by Ken Calhoun Version: 1.00 02/08/2016 Formula Parameters: Default: Gap Down 10 Trailing Stop 0.4 Notes: The related article is copyrighted material. If you are not a subscriber of Stocks & Commodities, please visit www.traders.com. **********************************/ var fpArray = new Array(); function preMain(){ setPriceStudy(true); var x=0; fpArray[x] = new FunctionParameter("GapDown", FunctionParameter.NUMBER); with(fpArray[x++]){ setLowerLimit(1); setUpperLimit(100); setDefault(10); setName("Gap Down %"); } fpArray[x] = new FunctionParameter("TrlStop", FunctionParameter.NUMBER); with(fpArray[x++]){ setLowerLimit(0.01); setDefault(0.4); setName("Trailing Stop"); } } var bInit = false; var xClose = null; var xOpen = null; var xHigh = null; var xLow = null; var bIsLong = false; var bGapFound = false; var vStopPrice = null; var bVersion = null; var vLowOfTheGap = null; var vGapDown = null; var vHighestHigh = null; function main(GapDown, TrlStop){ if (bVersion == null) bVersion = verify(); if (bVersion == false) return; if(getBarState() == BARSTATE_ALLBARS){ bInit = false; } if (!bInit){ xClose = close(inv("D")); xOpen = open(inv("D")); xHigh = high(); xLow = low(); bIsLong = false; bGapFound = false; vGapDown = GapDown/100; bInit = true; } if(xClose.getValue(-1) == null) return; var nPrevClose = xClose.getValue(-1); var nLow = xLow.getValue(0); var nHigh = xHigh.getValue(0); var nOpen = xOpen.getValue(0); if (day(-1) != day(0) && bGapFound) { bGapFound = false; bIsLong = false; } if (bIsLong){ if (nHigh > vHighestHigh && (nLow - TrlStop) > vStopPrice) { vStopPrice = (nLow - TrlStop); vHighestHigh = nHigh } else if (nLow <= vStopPrice){ bIsLong = false; bGapFound = false; drawTextRelative(0, AboveBar1, "\u00EA", Color.red, null, Text.PRESET|Text.CENTER, "Wingdings", 10, "Exit"+rawtime(0)); drawText("Suggested Long Exit at "+formatPriceNumber(vStopPrice),BottomRow1,Color.red,Text.LEFT,"Text Exit"+rawtime(0)); } } if (bGapFound && !bIsLong && nHigh > vLowOfTheGap) { drawTextRelative(0, BelowBar1, "\u00E9", Color.green, null, Text.PRESET|Text.CENTER, "Wingdings", 10, "Long"+rawtime(0)); drawText("Suggested Long Entry at "+formatPriceNumber(vLowOfTheGap),TopRow1,Color.green,Text.LEFT,"Text"+rawtime(0)); bIsLong = true; vStopPrice = (nLow - TrlStop); vHighestHigh = nHigh; } if( !bIsLong && !bGapFound && day(0)!=day(-1) && (nPrevClose - nOpen) >= (nPrevClose * vGapDown)){ vLowOfTheGap = nLow + 0.5; bGapFound = true; } return; } function verify(){ var b = false; if (getBuildNumber() < 779){ drawTextAbsolute(5, 35, "This study requires version 12.1 or later.", Color.white, Color.blue, Text.RELATIVETOBOTTOM|Text.RELATIVETOLEFT|Text.BOLD|Text.LEFT, null, 13, "error"); drawTextAbsolute(5, 20, "Click HERE to upgrade.@URL=https://www.esignal.com/download/default.asp", Color.white, Color.blue, Text.RELATIVETOBOTTOM|Text.RELATIVETOLEFT|Text.BOLD|Text.LEFT, null, 13, "upgrade"); return b; } else b = true; return b; }
In his article in this issue, “Trading Gap Reversals”, author Ken Calhoun discusses trading stocks after the price has had drastic change in between trading sessions. This drastic change creates a gap in the chart. This well-known technical analysis occurrence has been documented many times over, but Calhoun gives us some very specific rules on how to trade. We have built a filter and his strategy using our proprietary scripting language, thinkscript. We have made the loading process extremely easy; simply click on the link https://tos.mx/cV2VCR and choose view thinkScript strategy. Choose to rename it to “Strategy GapReversalLE.” You can adjust the parameters of this strategy within the edit studies window to fine-tune your variables.
In the example in Figure 4, you see a chart of Allison Transmission (ALSN) with the GapReversalLE strategy added. We have also added our exit strategies, TrailStopLX, with a $1.00 value based on the article. For more about the strategy, see Calhoun’s article.
FIGURE 4: THINKORSWIM. Here, the GapReversalLE strategy is added to a chart of Allison Transmission (ALSN).
Here, we’ll present the WealthScript code for use in Wealth-Lab based on Ken Calhoun’s article in this issue, “Trading Gap Reversals”.
Through parameter “sliders” at the bottom, you can tune this system by modifying parameters such as gap percent, trailing stop value, and thresold for entry (Figure 5).
FIGURE 5: WEALTH-LAB. Here is an example trade in FTNT (Fortinet) in January 2016.
This strategy’s code has been modified to trade only once a day, and exit as soon as the gap is closed, in addition to the other exits. It’s advised that motivated users also experiment with replacing the fixed-dollar variables with a fraction of ATR to make the system more adaptive. In addition, the rules can be reversed to explore the short side.
using System; using System.Collections.Generic; using System.Text; using System.Drawing; using WealthLab; using WealthLab.Indicators; namespace WealthLab.Strategies { public class TradingGapReversals : WealthScript { private StrategyParameter gapPct; private StrategyParameter buyStp; private StrategyParameter sellStp; public TradingGapReversals() { gapPct = CreateParameter("Gap %", 10, 1, 30, 1); buyStp = CreateParameter("Buy stop", 0.50, 0.10, 1.0, 0.1); sellStp = CreateParameter("Sell stop", 0.40, 0.10, 1.0, 0.1); } protected override void Execute() { DataSeries trigger = Bars.Close * (1 - gapPct.Value / 100) >> 1; int cnt = 0; for (int bar = 1; bar < Bars.Count; bar++) { if( Date[bar].Date > Date[bar-1].Date ) cnt++; Position p = LastPosition; if (IsLastPositionActive) { double amount = p.MFEAsOfBar(bar) / p.Shares + p.EntryPrice - sellStp.Value; if(!SellAtStop(bar+1, p, p.EntryPrice - sellStp.Value, "Initial")) if(!SellAtTrailingStop(bar+1, p, amount, "Trailing")) SellAtLimit(bar+1, p, p.AutoProfitLevel, "Gap closed"); } else if (p == null || !p.Active && p.EntryBar < (bar - Bars.IntradayBarNumber(bar))) { if( cnt > 0 ) { int firstBarToday = bar - Bars.IntradayBarNumber(bar); int lastBarYesterday = firstBarToday - 1; bool priceFilter = (Close[firstBarToday] >= 20) && (Close[firstBarToday] <= 70); bool gap = (Open[firstBarToday] <= trigger[lastBarYesterday]); if( priceFilter && gap && Bars.IntradayBarNumber(bar) > 0 ) { if( BuyAtStop(bar + 1, Low[firstBarToday] + buyStp.Value ) != null ) LastPosition.AutoProfitLevel = Close[lastBarYesterday]; } } } } } } }
The gap reversal trading system described by Ken Calhoun in his article in this issue, “Trading Gap Reversals”, can be easily implemented with a few of NeuroShell Trader’s 800+ indicators. Simply select new trading strategy from the insert menu and enter the following in the appropriate locations of the trading strategy wizard:
BUY LONG CONDITIONS: [All of which must be true] A<=B<=C(20,Close,70) A>B(DayRange(Date,High,Low,1),1.0) A>=B(Volume,15000) A<=B(Divide(DayOpen(Date,Open,0),DayClose(Date,Close,1)),0.9) A<B(DayHigh(Date,Sub(High,DayLow(Date,Low,0)),0),0.5) BUY STOP PRICE: Add2(DayLow(Date,Low,0),0.5) LONG TRAILING STOP PRICES: TrailPricePnts(Gap Reversal Trading Strategy,0.4)
A sample chart is shown in Figure 6.
FIGURE 6: NEUROSHELL TRADER. This NeuroShell Trader chart shows the gap reversal trading strategy.
If you have NeuroShell Trader Professional, you can also choose whether the parameters should be optimized. After backtesting the trading strategy, use the detailed analysis button to view the backtest and trade-by-trade statistics for the strategy.
Users of NeuroShell Trader can go to the Stocks & Commodities section of the NeuroShell Trader free technical support website to download a copy of this or any previous Traders’ Tips.
The AIQ code based on Ken Calhoun’s article in this issue, “Trading Gap Reversals”, is provided at www.TradersEdgeSystems.com/traderstips.htm.
Since I mainly work with daily bar strategies, I wanted to test the gap-down concept on a daily bar trading system rather than on one-minute bars. I set up a system that buys after a stock has gapped down at least 10% in the last two days and then trades above the high of the gap-down bar. The entry is then at the close of that bar. For exits, I used the built-in exit, the profit-protect exit set at 80% once profit reaches 3% or more combined with a stop-loss using the low of the gap-down bar and also a time exit set to five bars. I then ran this system on the NASDAQ 100 list of stocks in the EDS backtester over the period 12/31/1999 to 1/11/2016 (Figure 7). The system generated 303 trades with an average profit of 1.09% per trade with a reward-to-risk ratio of 1.35. Slippage and commissions have not been deducted from these results.
FIGURE 7: AIQ. This shows the EDS test results for the example system.
Again, the code and EDS file can be downloaded from www.TradersEdgeSystems.com/traderstips.htm, and is also shown below.
!TRADING GAP REVERSALS !Author: Ken Calhoun, TASC April 2016 !Coded by: Richard Denning 2/1/2016 !www.TradersEdgeSystems.com !INPUTS: GapSize is 10. GapLookBack is 5. MaxBars is 5. !CODING ABBREVIATIONS: H is [high]. C is [close]. C1 is val([close],1). L is [low]. O is [open]. GapD is (O / C1 - 1) * 100. GapOS is scanany(GapD < -GapSize,GapLookBack) <> nodate() then offsettodate(month(),day(),year()). Hgap is valresult(H,^GapOS). Lgap is valresult(L,^GapOS). SU if scanany(GapD < -GapSize,GapLookBack). SU1 if scanany(GapD < -GapSize,GapLookBack,1). SU2 if scanany(GapD < -GapSize,GapLookBack,2). LE if ((SU1 then resetdate()) or (SU2 then resetdate())) and H > Hgap. ExitLong if {position days} > maxBars or C < Lgap. EntryPr is max(O,Hgap). List if C > 0.
The TradersStudio code based on Ken Calhoun’s article in this issue, “Trading Gap Reversals,” can be found at www.TradersEdgeSystems.com/traderstips.htm.
The following code file is provided in the download:
System: GAP_R_SYS — A daily bar system that goes long only on large gap-down reversals.
Since I mainly work with daily bar strategies, I wanted to test the gap-down concept on a daily bar trading system rather than on one-minute bars. I set up a system that buys after a stock has gapped down at least 15% in the last six days and then trades above the high of the gap-down bar. The entry is the next bar at market open. For exits, I used a profit-protect exit set at 40% once profit reaches 1% or more combined with a stop-loss using the low of the gap-down bar and also a time exit set to nine bars.
I then ran this system on the NASDAQ 100 list of stocks in the EDS backtester over the period 12/31/1999 to 7/11/2014. The system generated 129 trades with an average profit of 1.90% per trade with a profit factor of 1.89. Slippage and commissions have not been deducted from these results.
I found these parameters by optimization. I do not believe that there are enough trades to constitute a viable trading system. This pattern could be used in combination with other patterns to allow for enough trades. In addition, a larger list of stocks such as the Russell 1000 could be tried, and then there might be enough trades to use this pattern alone as a trading system.
Figure 8 shows the equity curve and underwater equity curve trading all signals at 200 shares per trade without deducting slippage or commissions.
FIGURE 8: TRADERSSTUDIO. Shown here are the equity and underwater equity curves for the gap reversal system trading NASDAQ 100 stocks.
The TradersStudio code is shown here:
'TRADING GAP REVERSALS 'Author: Ken Calhoun, TASC April 2016 'Coded by: Richard Denning 2/11/2016 'www TradersEdgeSystems com Sub GAP_R(GapSize,GapLB,MinTSclose,MaxBars,ppTrig,PftProtect) 'INPUTS: 'GapSize = 15 'GapLB = 6 'MinTSclose = 5 'MaxBars = 9 'ppTrig = 1 'PftProtect = 40 Dim GapD As BarArray Dim GapOS As BarArray Dim Hgap As BarArray Dim Lgap As BarArray Dim n If C[1] <> 0 Then GapD = (O / C[1] - 1) * 100 For n = 1 To GapLB If GapD[n] < -GapSize Then Hgap = H[n] Lgap = L[n] If H > Hgap And TSCLose > MinTSclose Then Buy("LE",1,0,Market,Day) If C < Lgap Then ExitLong("LXstop","",1,0,Market,Day) End If Next If BarsSinceEntry > MaxBars Then ExitLong("LXtime","",1,0,Market,Day) Dim hiTradePft,curPft If EntryPrice <> 0 Then curPft = C/EntryPrice-1 hiTradePft = (Highest(C,BarsSinceEntry)/EntryPrice-1)*100 If hiTradePft > 0 Then If hiTradePft > ppTrig And curPft/hiTradePft < PftProtect Then ExitLong("ProfitProtect","",1,0,Market,Day) End If End If End If End Sub
In “Trading Gap Reversals” in this issue, Ken Calhoun presents a very simple strategy based on -10% price gaps occurring in premarket data. A ready-to-use exploration formula that finds such opportunities is shown in the code listing here. To use the formula, enter the code in the formula editor and press send to analysis to perform explorations. Be sure to use a data source that feeds premarket data, and remember to switch the periodicity to one minute and the date range to last day.
// looking for -10% intraday gaps since prior day close prevclosedaily = TimeFrameGetPrice( "C", inDaily, -1 ); maxgap = 100 * ( Low - prevclosedaily ) / prevclosedaily; curchange = 100 * ( Close - prevclosedaily ) / prevclosedaily; buystoplevel = Low + 0.5; Filter = Close > 20 AND Close < 70 AND maxgap < -10; AddColumn( Close, "Last price" ); AddColumn( maxgap, "Max gap" ); AddColumn( curchange, "Current change" ); AddColumn( buystoplevel, "Buy stop level" );
A NinjaTrader indicator and strategy based on the article by Ken Calhoun in this issue, “Trading Gap Reversals”, are available for download at www.ninjatrader.com/SC/April2016SC.zip.
Once downloaded, from within the NinjaTrader Control Center window, select the menu File → Utilities → Import NinjaScript and select the downloaded file. This file is for NinjaTrader Version 7.
You can review the indicator’s and the strategy’s source code by selecting the menu Tools → Edit NinjaScript → and either Indicator or Strategy from within the NinjaTrader Control Center window and then selecting either the GapReversalIndicator or GapReversalStrategy file.
A sample chart implementing the strategy is shown in Figure 9.
FIGURE 9: NINJATRADER. The GapReversalIndicator and volume are displayed on the FTNT one-minute chart for the session break between January 19 and 20.
Our Traders’ Tips for this month is based on “Trading Gap Reversals” in this issue by Ken Calhoun.
In his article, Calhoun proposes that major gap downs are typically seen as oversold and thus present buying opportunities in stocks less likely to fall lower. This system trades on major gap downs (parameterized as 10% from the previous day’s low) when the gap begins to be closed within the first hour of trading. Exits are based on crossing a trailing $0.40 stop.
The Updata code based on Calhoun’s article is in the Updata library and may be downloaded by clicking the custom menu and system library. Those who cannot access the library due to a firewall may paste the code shown here into the Updata custom editor and save it.
PARAMETER "%" @PCT=10 PARAMETER "Stop [Cent]" @STOP=0.40 NAME "GAP TRADER" "" DISPLAYSTYLE 4LINES INDICATORTYPE TOOL COLOUR RGB(0,0,0) PLOTSTYLE2 THICK2 RGB(0,0,200) PLOTSTYLE3 THICK2 RGB(200,0,0) COLOUR4 RGB(150,150,150) @RUNNINGHIGH=0 @RUNNINGLOW=0 @THISDAYOPEN=0 @LASTDAYCLOSE=0 @LASTDAYHIGH=0 @LASTDAYLOW=0 @LASTDAYOPEN=0 @PCTFALL=0 @STOPTRAIL=0 FOR #CURDATE=0 TO #LASTDATE IF #CURDAY!=HIST(#CURDAY,1) 'Finds Last Daily OHLC @LASTDAYCLOSE=HIST(CLOSE,1) @LASTDAYHIGH=HIST(@RUNNINGHIGH,1) @LASTDAYLOW=HIST(@RUNNINGLOW,1) @LASTDAYOPEN=HIST(@THISDAYOPEN,1) 'At the start of a new day, initialise OHL values @RUNNINGHIGH=HIGH @RUNNINGLOW=LOW @THISDAYOPEN=OPEN ENDIF 'Tracks this daily High & Low IF HIGH>@RUNNINGHIGH @RUNNINGHIGH=HIGH ELSEIF LOW<@RUNNINGLOW @RUNNINGLOW=LOW ENDIF IF (100*(@LASTDAYLOW-@RUNNINGLOW)/@RUNNINGLOW)>@PCT @PCTFALL=1 ELSE @PCTFALL=0 ENDIF IF ORDERISOPEN=1 @STOPTRAIL=MAX(CLOSE-@STOP,@STOPTRAIL) IF CLOSE<@STOPTRAIL SELL @STOPTRAIL ENDIF ENDIF 'ENTRY IF GAP DOWN X% AND RALLY OF 50C HAS OCCURED IF @PCTFALL>0.5 AND HIGH-@RUNNINGLOW>0.5 AND ORDERISOPEN<1 BUY HIGH @STOPTRAIL=OPEN-@STOP ENDIF 'Plots OHLC for previous day '@PLOT=@LASTDAYOPEN @PLOT2=@LASTDAYHIGH @PLOT3=@LASTDAYLOW @PLOT4=@LASTDAYCLOSE NEXT
Figure 10 shows a chart of the gap reversal system implemented on the chart of Fortinet Inc. along with the equity curve.
FIGURE 10: UPDATA. This chart shows the gap reversal system entering a long in Fortinet Inc. earlier this year.