Hello All,
I'm quite new to Amibroker and still learning. This forum and the Amibroker tutorials has been excellent in getting me started.
I am however now stuck with an Issue where I need some guidance on how to manage data.
Background: i'm coding a Long only strategy based on relative strength of a stock against a benchmark index. I want to buy the top 10 ranked stocks, and hold them until they have dropped out of the Top 20 ranks. The ranks should be evaluated every week on daily timeframe data.
Problem: As the title states, while in most rotations the correct stocks are being rotated in/out based on the ranks, during some rotations the strategy exits longs and shorts some stocks.
I tested this in a narrow date range to better show the problem.
The stocks that the code is shorting for e.g. on 8-Nov-2010 are from the previous trading day i.e. 05-Nov-2010 where my database doesn't have the data for these stocks for that day.
Exploration that explains this
Please let me know how I can work around these data holes. BTW, I do have Pad & align turned on and the the bar exists in the reference symbol.
My code below for reference in case there's any workaround that I can implement in the code itself.
// set all the backtest settings in AFL code so that its standardized across backtests.
SetFormulaName("Rotational Weekly");
SetBacktestMode(backtestRotational);
// 1 ###### BACKTESTER SETTINGS - 1. GENERAL TAB
PosQty = Optimize("PosQty", 10, 5, 20, 1);
WorstRank = Optimize("WorstRank", 20, 10, 40, 5);
SetOption("InitialEquity", 1000000); //
SetOption("MinShares", 1); // atleast buy 1 share, no fractional shares
SetOption("MinPosValue", 0);
SetOption("FuturesMode", False);
SetOption("AllowPositionShrinking", True);
SetOption("ActivateStopsImmediately", True);
SetOption("ReverseSignalForcesExit", False);
SetOption("AllowSameBarExit", True);
RoundLotSize = 1;
SetOption("CommissionMode", 1); //1= % of trade; 2 - $ per trade; 3 - $ per share/contract
SetOption("CommissionAmount", 0.07); // STT = 0.0005 for each buy & sell; Transaction charges NSE: 0.0000325; Fixed DP Charge on Sell: Rs. 15.93 - just setting to 0.07 on higher side
SetOption("AccountMargin", 100); // AccountMargin - account margin requirement 100 = no margin
SetOption("UsePrevBarEquityForPosSizing", True);
// 2 ###### BACKTESTER SETTINGS - 2. TRADES TAB - Trade timing
BuyPrice = SellPrice = Open;
SetTradeDelays(1,1,1,1); // Trades are entered 1 day after signal is generated i.e. next week open as coded
// 5 ###### BACKTESTER SETTINGS - 5. PORTFOLIO TAB - position sizing etc
SetOption("MaxOpenPositions", PosQty);
// Limit trade size as % - use 10 for live trading
// check the box to "Disable trade size limit..."
SetOption("UsePrevBarEquityForPosSizing", True);
SetOption("UseCustomBacktestProc", False);
SetOption("WorstRankHeld", WorstRank);
SetOption( "MaxOpenLong", PosQty );
SetPositionSize(100/PosQty,spsPercentOfEquity); // calculate position size as % of equity automatically based on max # of stocks held
//SetOption("SeparateLongShortRank", True ); // not needed?
//######################## Strategy Code ########################
// watchlist should contain all symbols included in the test
wlnum = GetOption( "FilterIncludeWatchlist" );
List = CategoryGetSymbols( categoryWatchlist, wlnum ) ;
ListQty = StrCount(List, ",") + 1;
// Index optimizer
RSIndex = "^CRSLDX";
RSIndexMA = 34;
IndexClose = 0;
IndexMA = 0;
// Iterate through all stocks in watchlist to calculate RS at each periodicity
// Relative Strength calculation of stocks
// This code must be run in Analysis Engine with Daily periodicity.
if( Status( "stocknum" ) == 0 )
{
// Clear the static vars from last run, not required, but safer
StaticVarRemove("RS*");
StaticVarRemove("RankRS*");
IndexRSRatio55 = 0;
//######################## Get Index values to calculate relative strength ########################
SetForeign(RSIndex); //switch away to Index for calculating Index ratio. Done before the loop so its only called once
IndexRSRatio55 = C/Ref(C, -55);
RestorePriceArrays(); //switch back to current symbols
// Generate the raw RS score for every stock and store in a static var
for (n = 0; (Symbol = StrExtract(List, n)) != ""; n++)
{
SetForeign (Symbol,0);
StockRS55 = 0;
StockRS55 = ((C/Ref(C,-55)) / IndexRSRatio55 ) -1; // Last 3 months RS
// Set static var values referenced to the current symbol in the loop
StaticVarSet("RS_" + Symbol, 1000+StockRS55);
StaticVarSet("RSValue" + Symbol, StockRS55);
_TRACE(Date() +" Ticker="+Symbol +" RSValue="+ NumToStr(StockRS55) );
RestorePriceArrays();
}
// rank the stocks
StaticVarGenerateRanks("Rank", "RS_", 0, 1234);
}
Rank = StaticVarGet ("RS_" + Name());
EndOfWeek = DayOfWeek() > Ref( DayOfWeek(), 1 ); //looks ahead so can't use in realtime
PositionScore = IIf(EndOfWeek, Rank, scoreNoRotate);
//PositionScore = Rank;
// read ranking for debugging
/*
for (n = 0; (Symbol = StrExtract(List, n)) != ""; n++)
{
//_TRACE("Rank="+ NumToStr(n) +"-"+ Symbol);
_TRACE(Date() +" Ticker="+Symbol +" RSValue="+ NumToStr(StaticVarGet("RSValue"+Symbol)) +" Rank="+ NumToStr(StaticVarGet("RankRS_"+Symbol)) );
}
*/
SetSortColumns(3);
//######################## Exploration Section ########################
if( Status( "Action" ) == actionExplore )
{
Filter = (C > 1.0);
AddColumn(Close, "Price", 1.2);
AddColumn(Rank, "Rank", 1.3);
AddColumn(MA(Close, 20), "20 SMA", 1.3);
SetSortColumns(2, -4);
}