#include_once "Formulas\Norgate Data\Norgate Data Functions.afl"
stockInIndex = NorgateIndexConstituentTimeSeries("$XAO.AU");
stockIn200 = NorgateIndexConstituentTimeSeries("$XJO.AU");
stockIn50 = NorgateIndexConstituentTimeSeries("$XFL.AU");
OnSecondLastBarOfDelistedSecurity = !IsNull(GetFnData("DelistingDate")) AND (BarIndex() == (LastValue(BarIndex()) -1) OR DateTime() >= GetFnData("DelistingDate") ) ;
OnLastTwoBarsOfDelistedSecurity = !IsNull(GetFnData("DelistingDate")) AND (BarIndex() >= (LastValue(BarIndex()) -1) OR DateTime() >= GetFnData("DelistingDate") );
_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
InitialEquity= 20000;
SetOption( "InitialEquity", InitialEquity ); // $20k 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", 6 ); // 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
//=================================================================================
Index = Foreign("$XAO.au","C",True);
MAfilter = MA( Index, 10 ); // 10 week lookback period
IndexBuyFilter = Index > 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 = Index < 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]
RestorePriceArrays( True ); // Restores original arrays after the call to SetForeign.
//=================================================================================
//3. Add all our other filters
//=================================================================================
Liq = C * V; // Liquidity Filter
CV = 2000000; // 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
//=================================================================================
Cond1 = C > Ref( HHV( C, 10 ), -1 ); // Buy when the closing price is greater than the highest High Value of the last 20 weeks
Cond2 = IndexBuyFilter; // Buy ONLY when the Index Filter is ON
cond3 = C >= .05; // Buy only if the closing price is greater $0.05 (5 cents)
cond4 = C <= 10000; // 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
AND NOT OnLastTwoBarsOfDelistedSecurity
// AND stockinindex
;
//=================================================================================
//5. Add a sell condition
//=================================================================================
Sell = C < MA( C, 30 ) 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
Sell = Sell OR OnLastTwoBarsOfDelistedSecurity;
//=================================================================================
//6. Add a two-stage trailing stop
//=================================================================================
ts1 = 20;
ts2 = 8;
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.00; // +3% Buy premium over the last closing price
BuyOffer = floor( BuyOffered * 100 ) / 100; // The amount is rounded up no matter the price (ceil function used)
SellOffered = Close * 1.00; // -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)
s1 = Sell; // s1 are the original sell signals
if( Status("action") == actionExplore )
{
SetTradeDelays(0,0,0,0);
PositionScore = Positionscorer;
Equity( 2 );
SetSortColumns( 3,-4);
}
Filter = Filter = Status("LastBarInRange") AND (Buy OR Sell); // Buy & Sell Filters
ts = 0; // text selector ....
ts = IIf(Buy,1,0); // Buy signal
ts = IIf(s1,2,ts); // Sell signal
ts = IIf(Sell AND NOT s1,3,ts); // Stop signal
tl = "\nBuy\nSell\nStop"; // String array.
//addmultiTextColumn (ts,tl,"Action",1.2,colorWhite,IIf(Buy,colorDarkGreen,IIf(s1,colorRed,colorOrange)),60);
/***************** HIDE COLUMNS FOR VISUAL ***************/
AddColumn(IIf( Buy, BuyOffer, Null ),"Buy",1.2,colorWhite,IIf(Buy,colorDarkGreen,colorWhite),60);
AddColumn(IIf( Sell, SellOffer, Null),"Sell",1.2,colorWhite,IIf(S1,colorRed,colorWhite),60);
AddColumn(IIf(Sell and NOT s1,SellOffer,0),"Stop",1.2,colorWhite,IIf(Sell AND NOT s1,colorOrange,colorWhite),60);
AddColumn(PositionScorer,"Score");
//AddTextColumn("WTT","Strategy");
//AddTextColumn("ASX","Universe");
//AddTextColumn("MOO","Order Type");
//AddColumn(0,"Buy Stop",1.4); // No buy stop
//AddColumn(0,"Buy LMT"); // no limit
//AddColumn(0,"Sell LMT"); // no limit
AddColumn(-positionSize,"Position Size %");
AddColumn(-positionsize*InitialEquity/100/C,"# Shares");
AddColumn(ts,"ts"); //
//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
PlotShapes(Buy*shapeUpArrow,colorGreen,0,Low);
PlotShapes(Sell*shapeDownArrow,colorRed,0,High);
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();
//=================================================================================
//Bonus Section - Additional Metrics - Win/Loss ratio
//=================================================================================
_SECTION_BEGIN( "Win/Loss Ratio" );
// BONUS - Additional Metrics - Win/Loss ratio for the previous years and includes the number of trades per year
procedure vgWinLossPerYear( YrWin, YrLoss, Yrcnt, trade, mode )
{
dt = IIf( mode == 1, trade.ExitDateTime, trade.EntryDateTime );
n = floor( DateTimeConvert( 8, dt ) );
if( trade.GetProfit() >= 0 ) // profit only
VarSet( YrWin + n, Nz( VarGet( YrWin + n ) ) + 1 );
else // loss only
VarSet( YrLoss + n, Nz( VarGet( YrLoss + n ) ) + 1 );
// cnt all per year
VarSet( Yrcnt + n, Nz( VarGet( Yrcnt + n ) ) + 1 );
}
SetCustomBacktestProc( "" );
if( Status( "action" ) == actionPortfolio )
{
bo = GetBacktesterObject();
bo.Backtest();
yr = Year();
fbr = Status( "FirstBarInRange" );
lbr = Status( "LastBarInRange" );
first_yr = LastValue( ValueWhen( fbr, yr ) );
last_yr = LastValue( ValueWhen( lbr, yr ) );
// iterate closes trades
for( trade = bo.GetFirstTrade(); trade; trade = bo.GetNextTrade() )
vgWinLossPerYear( "YrWin", "YrLoss", "Yrcnt", trade, 0 );
// iterate open trades
for( trade = bo.GetFirstOpenPos(); trade; trade = bo.GetNextOpenPos() )
vgWinLossPerYear( "YrWin", "YrLoss", "Yrcnt", trade, 0 );
// Output per year stats to report file
for( i = first_yr; i <= last_yr; i++ )
{
YrCnt = VarGet( "Yrcnt" + i );
bo.AddCustomMetric( StrFormat( "Year%g (%g trades): WinRatio %1.2f%%, LossRatio %1.2f%%",
i, YrCnt, VarGet( "YrWin" + i ) / YrCnt * 100, VarGet( "YrLoss" + i ) / YrCnt * 100 ) );
}
}
_SECTION_END();