Need some help with CBT.
In the following CBT code, I want to buy on First of Month with delay =1,
MaxOpenPos of 3 and Worst1 of 6. This works fine.
On other than First of Month, want to test the following:
(1) Is it best to sell a ticker and not replace if ranking
for the ticker falls to below Worst2 which is 10, or,
(2) Is it best to replace ticker (on other than first of month)
when ranking for the ticker falls to below Worst2.
I can not get CBT to work for (1) and (2). See below.
Numbers (1) and (2) can be tested separately. In the end, want primary buys to
be on first of month with delay of 1 and to only take action on any other day
of the month if held ticker's ranking drops below Worst2 of 10. This means
that one will see few buys and few sells on other than the first of the month.
Here is the example CBT code:
// Rotation_with_MidLevelCBT.afl
// An example using Mid Level CBT
MaxOpenPos = 3;//Optimize("MaxOpenPos",3,3,26,1);
Worst1 = 6;// WorstRankHeld for 1st of month only
Worst2 = 10;//Optimize("Worst2",15,6,26,1);// WorstRankHeld for rest of month
BuyPrice = SellPrice = ShortPrice = CoverPrice = Close;
Delay = 1;
SetTradeDelays( Delay, Delay, Delay, Delay );
SetOption("MaxOpenPositions", MaxOpenPos );
SetOption("WorstRankHeld", Worst2 );
EnableRotationalTrading( True );
PositionSize = -100/GetOption("MaxOpenPositions");
firstofmonth = Month() != Ref( Month(), -1 );
firstofmonth2 = Ref(firstofmonth,-Delay);// Need for Mid Level Backtester
Rank = 1/RSI(14);
PositionScore = rank;
//PositionScore = IIf( firstofmonth, Rank, scoreNoRotate );
// THIS IS MID LEVEL BACKTESTER
// Want to buy on First of Month with delay =1, MaxOpenPos of 3
// and Worst1 of 6.
// On other than First of Month, want to test the following:
// (1) Is it best to sell a ticker and not replace if ranking
// for the ticker falls to below Worst2 which is 10, or,
// (2) Is it best to replace ticker (on other than first of month)
// when ranking for the ticker falls to below Worst2.
// Note: Numbers (1) and (2) can be tested separately. In the end,
// want most (90+ percent) of the buys to be on first of month
// with delay of 1 and to only take action on any other day of
// the month if held ticker's ranking drops below Worst2 of 10.
// This means that one will see few buys and few sells on other
// than the first of the month.
SetOption("UseCustomBacktestProc", True );
//SetOption("UseCustomBacktestProc", False );
// FirstOfMonth with MaxOpenPos of 3 and Worst1 of 6.
// This section of code works just fine.
if( Status("action") == actionPortfolio )
{
bo = GetBacktesterObject();
bo.PreProcess();
for( bar = 0; bar < BarCount; bar++ )
{
if( firstofmonth2[ bar ] )
{
TopSymbols = "";
for( i = 0, sig = bo.GetFirstSignal( bar );
sig AND i < Worst1;
sig = bo.GetNextSignal( bar ), i++ )
{
TopSymbols += sig.Symbol + ",";
}
_TRACE("Top " + Worst1 + " Symbols: " + TopSymbols );
for( pos = bo.GetFirstOpenPos(); pos; pos = bo.GetNextOpenPos() )
{
if( NOT StrFind( TopSymbols, pos.Symbol + "," ) )
{
_TRACE("Exiting position not found in top list: " + pos.Symbol );
// exit the position
bo.ExitTrade( bar, pos.Symbol, pos.GetPrice( bar, "C" ), 9 ); //
modify price field if needed here
}
}
}
// On other than FirstOfMonth, want to sell a ticker if ranking falls below
// worst2 of 10 and not replace it until next FirstOfMonth. THE FOLLOWING
// DOES NOT WORK AS IT ROTATES INTO THE NEXT TICKER RATHER THAN JUST
// SELLING THE TICKER.
if( NOT firstofmonth2[ bar ] )
{
TopSymbols = "";
for( i = 0, sig = bo.GetFirstSignal( bar );
sig AND i < Worst1;
sig = bo.GetNextSignal( bar ), i++ )
{
TopSymbols += sig.Symbol + ",";
}
_TRACE("Top " + Worst2 + " Symbols: " + TopSymbols );
for( pos = bo.GetFirstOpenPos(); pos; pos = bo.GetNextOpenPos() )
{
if( NOT StrFind( TopSymbols, pos.Symbol + "," ) )
{
_TRACE("Exiting position not found in top list: " + pos.Symbol );
// exit the position, but do NOT replace position
bo.ExitTrade( bar, pos.Symbol, pos.GetPrice( bar, "C" ), 8 ); //
modify price field if needed here
}
}
}
/* Alternative code for second CBT code section above
// On other than FirstOfMonth, want to sell a ticker if ranking falls below
// worst2 of 10 and replace. THE FOLLOWING WORKS BUT IT SCREWS UP THE BUY DATES.
// STILL WANT THE PRIMARY BUYS TO BE ON THE FIRST OF THE MONTH WHICH DOES NOT
// HAPPEN WITH THE FOLLOWING CODE.
if( NOT firstofmonth2[ bar ] )
{
TopSymbols = "";
for( i = 0, sig = bo.GetFirstSignal( bar );
sig AND i < Worst1;
sig = bo.GetNextSignal( bar ), i++ )
{
TopSymbols += sig.Symbol + ",";
}
_TRACE("Top " + Worst2 + " Symbols: " + TopSymbols );
for( pos = bo.GetFirstOpenPos(); pos; pos = bo.GetNextOpenPos() )
{
if( NOT StrFind( TopSymbols, pos.Symbol + "," ) )
{
_TRACE("Exiting position not found in top list: " + pos.Symbol );
// exit the position, but do NOT replace position
bo.ExitTrade( bar, pos.Symbol, pos.GetPrice( bar, "C" ), 8 ); //
modify price field if needed here
}
}
}
*/
bo.ProcessTradeSignals( bar );
}
bo.PostProcess();
}
// The End
Thanks in advance for the help.