The WTT Strategy is a 20-week breakout strategy
I had planned to keep posting more about the "WTT Strategy" but trying to duplicate another persons strategy is next to impossible. I coded my version of the "WTT Strategy" as a simple exercise in constructing a strategy. The simple 12 step procedure might be helpful to some.
Uploads
The idea was to upload the constructed version of the "WTT Strategy" then show how a few simple modifications (parameters & settings) can improve the strategy performance. Posting 2 or 3 different codes would be confusing so I'll upload my modified version of the "WTT Strategy" & let others backtest the strategy for evaluation.
Human readable WTT code
The code below is the (AFL) Amibroker "WTT Strategy" code for those who don't own the Amibroker program. I have made comments on each line for a better understanding of what the line of code is hoping to achieve.
/********************************************
Skate's WTT Weekly Modified Strategy for ASF Members
Created by: Skate - Last revision 12th August 2020
*********************************************/
_SECTION_BEGIN( "# Skate's WTT Modified Exploration" );
//=================================================================================
//
1. The "SetOptions" are management options & they are a feature of Amibroker
//=================================================================================
TradingFunds = Param( "Trading Funds - $", 5000, 1000, 10000000, 1000 ); // User-definable parameter, accessible via Exploration parameters - changes are reflected immediately. (Default $5k bets) - INSERT any amount
SetOption( "InitialEquity", 100000 ); // $100k Inital Equity (allows for 20 X $5k bets)
SetOption( "PriceBoundChecking", 1 ); // True: Adjust prices so that they fall within the High-Low range
SetOption( "CommissionMode", 2 ); // Use $ amount
SetOption( "CommissionAmount", 19.95 ); // CommSec commission rate
SetOption( "UsePrevBarEquityForPosSizing", 1 ); // True: Use previous bar closing equity to perform position sizing
SetOption( "AllowSameBarExit", False ); // False: Trade is exited & we move to next bar ignoring other signals
SetForeign( "$XAO.au", True , True ); // I've used the new Norgate Updater (NDU) format - change if the format is different to your data supplier
RestorePriceArrays( True ); // Restores original price and volume arrays after the call to SetForeign.
SetTradeDelays( 1, 1, 1, 1 ); // Trade delays, the delay is required for backtesting
//=================================================================================
//
2. The "Index Filter" - decides when we will trade & also our trailing stop levels
//=================================================================================
MAfilter = MA( C, 10 ); // 10 week lookback period
IndexBuyFilter = C > MAfilter; // Index Filter = ON: When the close is greater than the 10 week simple moving average the Index Filter is ON [trailing stop set to 20%] + [buy + sell signals generated]
IndexSellFilter = C < MAfilter; // Index Filter = OFF: When the close is less than the 10 week simple moving average the Index Filter is OFF [shortens trailing stop to 10%] + [only sell signals generated]
//=================================================================================
//
3. Add all our other filters
//=================================================================================
Liq = C * V; // Liquidity Filter
CV = 500000; // Volume Filter
Liqfactor = Liq > CV; // Liquidity Filter
ROCFilter = ROC( C, 20 ) > 30; // Rate Of Change (ROC) Momentum filter
ROCParameter = Param( "ROC Parameter", 8, 0, 52, 1 ); // 8 week Rate of Change period
MOMFilter = ( ROC( C, 10 ) >= ROCParameter ); // Momentum filter - the closing price of the last 10 weeks is greater than the last 8 weeks
NoStrength = Close < MA( Close, 12 ); // If the closing price is less then the Simple Moving Average of the last 12 weeks it's considered there is no strength in the move
//=================================================================================
//
4. Add a Buy condition
//=================================================================================
WTTBP = Param( "Breakout Period", 10, 1, 1000, 1 ); // 10 week Lookback period
Cond1 = C > Ref( HHV( C, WTTBP ), -1 ); // Buy when the closing price is greater than the highest High Value of the last 10 weeks
Cond2 = IndexBuyFilter; // Buy ONLY when the Index Filter is ON
cond3 = C >= 0.05; // Buy only if the closing price is greater $0.05 (5 cents)
cond4 = C <= 10; // Buy only if the closing price is less than $10.00
cond5 = liqfactor; // Buy only when the Liquidity filter is TRUE
cond6 = ROCFilter AND MOMFilter; // Buy only when the Rate of Change filter & Momentum filter is TRUE
Buy = cond1
AND cond2
AND cond3
AND cond4
AND cond5
AND cond6;
//=================================================================================
//
5. Add a sell condition
//=================================================================================
Sell = C < MA( C, 50 ) AND NoStrength; // Sell when the close is less than the moving average of the last 50 weeks with the closing price is less than the Simple Moving Average of the last 12 weeks
//=================================================================================
//
6. Add a two-stage trailing stop
//=================================================================================
ts1 = 20;
ts2 = 10;
ts = IIf( Indexbuyfilter , ts1 , ts2 );
ApplyStop( stopTypeTrailing , stopModePercent , ts , exitatstop = 2 ); // Apply Stop = [ts] Trailing Stop [exitatstop = 2] means check High-Low prices but exit NEXT BAR on regular trade price.
//=================================================================================
//
7. Add "Position Sizing"
//=================================================================================
BuyPrice = Open; // Buy the next day at open
SellPrice = Open; // Sell the next day at open
Buy = ExRem( Buy, Sell ); // Removes additional buy signals
Sell = ExRem( Sell, Buy ); // Removes additional sell signals
PosQty = 20; // Position Quantity = Maximum 20 positions
PositionSize = -100 / posqty; // 100% of the equity divided by the Position Size
SetOption( "MaxOpenPositions", PosQty ); // Maximum number of open position
//=================================================================================
//
8. Add "Filters for the Exploration Analysis"
//=================================================================================
Filter = Buy OR Sell; // Buy & Sell Filters
//=================================================================================
//
9. Add Buy & Sell coding for use in trading the pre-auction
//=================================================================================
BuyOffered = Close * 1.03; // +3% Buy premium over the last closing price
BuyOffer = ceil( BuyOffered * 100 ) / 100; // The amount is rounded up no matter the price (ceil function used)
SellOffered = Close * 0.97; // -3% Sell premium below the last closing price
SellOffer = floor( SellOffered * 100 ) / 100; // The amount is rounded down no matter the price (floor function used)
//=================================================================================
//
10. Add the Exploration code
//=================================================================================
ToBuyPosSize = floor( TradingFunds / BuyOffer ); // Trading Funds divided by buy offer of (+3%) buy premium over the last closing price
ToBuyPosCost = BuyOffer * ToBuyPosSize; // The cost of buying the amount of share
PositionScorer = 100 - Close; // Lowest priced security at BuySetup trigger is taken first
PositionScore = Ref( PositionScorer, -1 ); // Previous bar (-1 bar)
//=================================================================================
//
11. Add columns to report & sort the Exploration Analysis results
//=================================================================================
AddColumn( IIf( Buy, ToBuyPosSize, Null ), "# shares", 1, colorWhite, colorDarkGreen, 90 ); // Exploration Analysis - this column displays quantity of shares to buy
AddColumn( IIf( Buy, BuyOffer, Null ), "$ Buy Offer", 1.2, colorWhite, colorDarkGreen, 110 ); // Exploration Analysis - this column displays pre-auction buy offer price (+3% premium added to the last closing price)
AddColumn( IIf( Buy, ToBuyPosCost, Null ), "$ Cost", 1.2, colorWhite, colorDarkGreen, 80 ); // Exploration Analysis - this column displays the total ($) you will pay for the qty of shares at the +3% primum
AddColumn( IIf( Sell, SellOffer, Null ), "$ Sell Offer", 1.2, colorWhite, colorRed, 110 ); // Exploration Analysis - this column displays pre-auction sell offer price (-3% discount to the last closing price)
SetSortColumns( 2, -3, -4, -5, -6, 1 ); // Sort the columns in correct order
_SECTION_END();
//=================================================================================
//
12. Add code to the chart & plots the signals. Also adding an Index Ribbon
//=================================================================================
_SECTION_BEGIN( "Price" );
SetChartOptions( 0, chartShowArrows | chartShowDates );
_N( Title = StrFormat( "{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) Vol " + WriteVal( V, 1.0 ) + " {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ) ); // Chart settings
Plot( C, "Close", ParamColor( "Color", colorBlack ),
ParamStyle( "Style", styleNoTitle | styleBar, maskAll ) ); // User-definable parameter, accessible via Chart parameters - changes are reflected immediatelly. (Bar Chart Default)
PlotShapes( Buy*shapehollowUpArrow, colorWhite, 0, Low, -20 ); // Displays Buy up arrow on the signal bar
PlotShapes( ( Sell > 0 ) * shapeDownArrow, Coloryellow, 0, High, -40 ); // Displays Sell down arrow on the signal bar
PlotShapes( Ref( Buy, -1 ) * shapeHollowSquare, colorWhite, 0, O, 0, 0 ); // Displays a white square on the buy bar
PlotShapes( Ref( Sell, -1 ) * shapeHollowCircle, colorYellow, 0, O, 0, 0 ); // Displays a yellow circle on the sell bar
Indexfilter = IIf( IndexBuyfilter, True, False ); // If Index Filter is TRUE (ON), or If Index Filter is FALSE (OFF),
RibbonColor = IIf( Indexfilter, colorGreen, colorRed ); // If Index Filter is TRUE (ON) the ribbon is GREEN, or If Index Filter is FALSE (OFF) the ribbon is Red
Plot( 1, "", RibbonColor, styleArea | styleOwnScale | styleNoLabel, -0.0001, 190 ); // Plots Index Filter Ribbon [green = ON] [Red = OFF]
for( i = 1; i < BarCount; i++ )
{
if( Buy[i - 1] ) PlotText( "Buy\n@ " + O
, i, L * 0.9, colorWhite ); // Displays white buy price (opening price) under the white box (buy bar)
if( sell[i - 1] ) PlotText( "Sell\n@ " + o[ i ], i, H[ i ] * 1.1, colorYellow ); // Displays yellow sell price (opening price) above the yellow circle (sell bar)
}
_SECTION_END();
Skate.