Home › Forums › Trading System Mentor Course Community › AmiBroker Coding and AFL › Using Composite Index in Backtester
- This topic is empty.
-
AuthorPosts
-
April 15, 2017 at 5:19 am #101632JulianCohenParticipant
Quick question. Is there a way to use a Compaosite Index in the backtester?
So if I add to a Composite Index in the first part of the code, can I then use that Index in the backtesting part of the code?
April 15, 2017 at 12:01 pm #106624SaidBitarMemberI think yes you can
April 15, 2017 at 12:21 pm #106626JulianCohenParticipantDo you know if I need to run a scan/explore first in order to propagate the composite index and then run a backtest?
I’m thinking that is the correct way to do it but I’m not sure.
April 15, 2017 at 12:22 pm #106627SaidBitarMemberyou need to run scan then the new ticker will be populated then you can use it
April 19, 2017 at 4:38 am #106625AnonymousInactiveJulian – I have used a composite index for backtesting and live trading and in my experience it worked as expected.
The way I set it up was to create the composite index using a separate AFL file. E.g. load the “index creator” AFL, scan, then open the main backtest AFL and run the test.
Not sure if the dual step process is necessary or not.
April 19, 2017 at 7:05 am #106651JulianCohenParticipantThanks Brent
I’m not sure I follow what you mean though…Could you show me a piece of code that illustrates this please?
April 19, 2017 at 7:45 pm #106654AnonymousInactiveSure Julian. For my reverse channel MOC system (the one with way too much selection bias), I was varying the position size based on the signal count (where signal count = the number of orders to be placed). So if I was placing 13 orders, my position size would be 15% of equity, if 14 orders, my positions size would be 14.5% of equity and so on until if signal count was 40+, the position size would be 5% of equity.
In order for the exploration or backtest to handle this, I had to create a custom index which I called ~SignalsLive. So I created an AFL which captured the number of buy signals for the following day and stored them in the index ~SignalsLive – before running the backtest or exploration, I load this AFL (“~SignalsLiveGenerator) and that creates the index.
Next, I load the AFL for the exploration or the backtest and reference the data stored in the ~SignalsLive index to either run an exploration or a backtest.
I will post both AFLs in full below.
April 19, 2017 at 7:46 pm #106661AnonymousInactiveHere is the AFL that generates the custom index. I load this first and scan. This creates the custom index (~SignalsLive).
Code:#include_once “FormulasNorgate DataNorgate Data Functions.afl”//——————————————————————-
//Historical Constituents
//——————————————————————-
USHistDB = NorgateIndexConstituentTimeSeries(“$RUI”);HDBFilter = USHistDB;
//——————————————————————-
//Optional Price & Volume Filters
//——————————————————————-
PriceTog = ParamToggle(“Price Filter”,”Off|On”,1);
PF = NorgateOriginalCloseTimeSeries();
MinSP = Param(“Minimum Share Price – $”,10,0.00,1000,.01);
MaxSP = Param(“Maximum Share Price – $”,100,0.00,2000,.01);
MinMaxSP = PF >= MinSP AND PF <= MaxSP; PriceFilt = IIf(PriceTog,MinMaxSP,1); //------------------------------------------------------------------- TOTog = ParamToggle("Turnover Filter","Off|On",1); Turnover = PF*V; MinTO = Param("Minimum Turnover - $",1000000,0,50000000,500000); TOMA = Param("Turnover MA",7,1,200,1); AveTO = EMA(Turnover,TOMA); TOFilter = AveTO >MinTO AND Turnover > MinTO;
TOFilt = IIf(TOTog,TOFilter,1);
//——————————————————————-
OptFilt = PriceFilt AND TOFilt;
//——————————————————————-//——————————————————————-
//System Parameters
//——————————————————————-_SECTION_BEGIN(“System Parameters”);
CLB = Param(“Channel Lookback”,5,5,5,1);
LowChan = LLV(C,CLB);_SECTION_END();
//******************************************************
//Buy / Sell Rules
//******************************************************Cond1 = OptFilt AND HDBFilter;
Cond2 = C < Ref(LowChan,-1); BuySetUp = Cond1 AND Cond2; //Number of Signals AddToComposite(BuySetUp == 1,"~SignalsLive","X",atcFlagDeleteValues|atcFlagEnableInBacktest|atcFlagEnableInExplore); SignalCount = Foreign("~SignalsLive","X"); Filter = SignalCount; AddColumn(SignalCount,"SignalCount",1);April 19, 2017 at 7:49 pm #106662AnonymousInactiveNow that the ~SignalsLive index is created, I load my code for exploration or backtest, which in turn references the index that was created by the other file. Note that in order for it to process correctly, you need to create another variable that references the index. This line of code does that:
SignalCount = Foreign(“~SignalsLive”,”X”);
and the full backtest code:
Code:#include_once “FormulasNorgate DataNorgate Data Functions.afl”_SECTION_BEGIN(“MCS Monte Carlo Part 1 of 2”);
//——————————————————————-
//MCS Monte Carlo Part 1 of 2
//——————————————————————-
Runs = Param(“Number of Runs”,20,0,100000,100);
Run = Optimize(“Run”,1,1,Runs,1);
MCP = Param(“Probability of Ignoring any Entry Signal %”,20,.000001,100,.000001);//——————————————————————-
//Historical Constituents
//——————————————————————-
USList = ParamList(“US Historical Watchlist:”,”1: Off|2: Russell 1000|3: Russell 2000|4: Russell 3000|5: NASDAQ 100|6: Dow Jones Industrial Average|7: S&P 500|8: S&P 100|9: S&P MidCap 400|10: S&P SmallCap 600|11: S&P 1500|12: Russell MicroCap|13: Russell MidCap|14: RTY ex CCMP|15: CCMP ex RTY|16: ASX 300|17: S&P 500 ex S&P 100″,0);
USHistDB = 1;
if(USList == “1: Off”) USHistDB = 1;
if(USList == “2: Russell 1000”) USHistDB = NorgateIndexConstituentTimeSeries(“$RUI”);
if(USList == “3: Russell 2000”) USHistDB = NorgateIndexConstituentTimeSeries(“$RUT”);
if(USList == “4: Russell 3000”) USHistDB = NorgateIndexConstituentTimeSeries(“$RUA”);
if(USList == “5: NASDAQ 100”) USHistDB = NorgateIndexConstituentTimeSeries(“$NDX”);
if(USList == “6: Dow Jones Industrial Average”) USHistDB = NorgateIndexConstituentTimeSeries(“$DJI”);
if(USList == “7: S&P 500”) USHistDB = NorgateIndexConstituentTimeSeries(“$SPX”);
if(USList == “8: S&P 100”) USHistDB = NorgateIndexConstituentTimeSeries(“$OEX”);
if(USList == “9: S&P MidCap 400”) USHistDB = NorgateIndexConstituentTimeSeries(“$MID”);
if(USList == “10: S&P SmallCap 600”) USHistDB = NorgateIndexConstituentTimeSeries(“$SML”);
if(USList == “11: S&P 1500”) USHistDB = NorgateIndexConstituentTimeSeries(“$SP1500”);
if(USList == “12: Russell MicroCap”) USHistDB = NorgateIndexConstituentTimeSeries(“$RUMIC”);
if(USList == “13: Russell MidCap”) USHistDB = NorgateIndexConstituentTimeSeries(“$RMC”);
if(USList == “15: CCMP ex RTY”) USHistDB = NorgateIndexConstituentTimeSeries(“$NDX”) AND NOT NorgateIndexConstituentTimeSeries(“$RUT”);
if(USList == “14: RTY ex CCMP”) USHistDB = NorgateIndexConstituentTimeSeries(“$RUT”) AND NOT NorgateIndexConstituentTimeSeries(“$NDX”);
if(USList == “16: ASX 300”) USHistDB = NorgateIndexConstituentTimeSeries(“$XKO”);
if(USList == “17: S&P 500 ex S&P 100”) USHistDB = NorgateIndexConstituentTimeSeries(“$SPX”) AND NOT NorgateIndexConstituentTimeSeries(“$OEX”);
if(USList == “18: Russell 1k ex S&P 500”) USHistDB = NorgateIndexConstituentTimeSeries(“$RUI”) AND NOT NorgateIndexConstituentTimeSeries(“$SPX”);
HDBFilter = USHistDB;//——————————————————————-
//Optional Price & Volume Filters
//——————————————————————-
PriceTog = ParamToggle(“Price Filter”,”Off|On”,1);
PF = NorgateOriginalCloseTimeSeries();
MinSP = Param(“Minimum Share Price – $”,10,0.00,1000,.01);
MaxSP = Param(“Maximum Share Price – $”,100,0.00,2000,.01);
MinMaxSP = PF >= MinSP AND PF <= MaxSP; PriceFilt = IIf(PriceTog,MinMaxSP,1); //------------------------------------------------------------------- TOTog = ParamToggle("Turnover Filter","Off|On",1); Turnover = PF*V; MinTO = Param("Minimum Turnover - $",1000000,0,50000000,500000); TOMA = Param("Turnover MA",7,1,200,1); AveTO = EMA(Turnover,TOMA); TOFilter = AveTO >MinTO AND Turnover > MinTO;
TOFilt = IIf(TOTog,TOFilter,1);
//——————————————————————-
OptFilt = PriceFilt AND TOFilt;
//——————————————————————-_SECTION_BEGIN(“Index Filter”);
//——————————————————————-
//Index Filter
//——————————————————————-
IndexTog = ParamToggle(“Index Filter”,”On|Off”,1);
IndexCode = ParamStr(“Index Symbol”,”$SPX”);
Index = Foreign(IndexCode,”C”);
IndMA = Param(“Index Filter MA”,200,2,1000,1);
IndexFilterUp = Index > MA(Index,IndMA);
IndexUp = IIf(IndexTog,1,IndexFilterUp);
//——————————————————————-
_SECTION_END();//Number of Signals
SignalCount = Foreign(“~SignalsLive”,”X”);FPAmt = 0;
for(i=1; i
= 40) {FPAmt[i] = 5.0;}
}ATRM = IIf(SignalCount <= 40,1,1.5); ATRP = Param("ATR Period",10,2,100,1); MyATR = ATR(ATRP); ATRL = MyATR*ATRM; //------------------------------------------------------------------- //System Parameters //------------------------------------------------------------------- _SECTION_BEGIN("System Parameters"); CLB = Param("Channel Lookback",5,4,30,1); LowChan = LLV(C,CLB); _SECTION_END(); OnSecondLastBarOfDelistedSecurity = BarIndex() == (LastValue(BarIndex()) -1) AND !IsNull(GetFnData("DelistingDate")); OnLastTwoBarsOfDelistedSecurity = BarIndex() >= (LastValue(BarIndex()) -1) AND !IsNull(GetFnData(“DelistingDate”));
//******************************************************
//Buy / Sell Rules
//******************************************************//Buy
Cond1 = HDBFilter AND OptFilt AND IndexUp;
Cond2 = C < Ref(LowChan,-1); BuySetUp = Cond1 AND Cond2; BuyLimit1 = C - ATRL; Tick = .05; BuyLimitVal = round(BuyLimit1/Tick); BuyLimit = BuyLimitVal*Tick; LE = Ref(BuySetUp,-1) AND L <= Ref(BuyLimit,-1) AND NOT OnLastTwoBarsOfDelistedSecurity; LEPrice = Min(O,Ref(BuyLimit,-1)); Limit2 = IIf(Ref(BuySetUp,-1),Ref(BuyLimit,-1),Null); Short = Cover = False; PriceAtBuy = 0; Buy = 0; Sell = 0; LBIT = 0; PriceAtBuy = 0; //------------------------------------------------------------------- //MCS Monte Carlo part 2 //------------------------------------------------------------------- if(MCP) LE = LE && Random()*100 >= MCP;//******************************************************
//Looping
//******************************************************for(j=1; j
0)
{
Sell[j] = True;
SellPrice[j] = C[j];
PriceAtBuy = 0;
}}
//******************************************************
//Plotting
//******************************************************//Basic chart display of O/H/L/C at the top
SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat(“{{NAME}} – {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}”, O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));//Format price display
ChartType = ParamList(“Chart Type”,”OHLC Bar|Candle|Line”,0); //specifying display options with OHLC Bar set to default
SetChartBkColor(ParamColor(“Chart Background Color”,colorBlack)); //allows chart background color to be adjustable
UpColor = ParamColor(“Up Candle/Bar Color”,colorGreen); //setting adjustable parameter for up candle color, default green
DownColor = ParamColor(“Down Candle/Bar Color”,colorRed); //setting adjustable parameter for up candle color, default red
Color1 = IIf(C>Ref(C,-1),UpColor,DownColor); //sets bar colors
Color2 = IIf (C > O,UpColor,DownColor); //sets candle colors
Color3 = ParamColor(“Line Chart Color”,colorRed); //sets default parameter for a line chart to red
TextColor = colorWhite;if(ChartType == “OHLC Bar”) ChartOption = styleBar;
if(ChartType == “Candle”) ChartOption = styleCandle;
if(ChartType == “Line”) ChartOption = styleLine;if(ChartType == “OHLC Bar”) ColorOption = Color1;
if(ChartType == “Candle”) ColorOption = Color2;
if(ChartType == “Line”) ColorOption = Color3;//Plotting
Plot(Close,”Close”,ColorOption,styleNoTitle|ChartOption|ParamStyle(“Chart Style”));
GraphXSpace = 10; //sets % of extra space above / below price action (without the adjustment, default is 2%)//Buy/Sell Signals
PlotShapes(shapeHollowUpArrow*BuySetUp,colorGreen,0,L,-80);
PlotShapes(shapeHollowSmallSquare*Buy,TextColor,0,BuyPrice,0);
PlotShapes(shapeHollowSmallSquare*Sell,colorYellow,0,SellPrice,0);
Plot(Ref(LowChan,-1),”Lower Channel”,colorAqua,styleDots);
Plot(Limit2,”Limit”,colorGrey40,styleArea);//Index filter status
RibbonColor = IIf(IndexFilterUp,colorGreen,colorRed);
Rib = IIf(IndexTog,Null,1);
Plot(Rib,””,RibbonColor,styleArea|styleOwnScale|styleNoLabel,-0.0001,190);//******************************************************
//Account / Sizing
//******************************************************_SECTION_BEGIN(“Position Sizing”);
Capital = Param(“Initial Equity $”,100000,1000,10000000,100);
SetOption(“InitialEquity”,Capital);MarginAmount = Param(“LTV %”,50,1,100,1);
SetOption(“AccountMargin”,MarginAmount);SetPositionSize(FPAmt,spsPercentOfEquity);
MaxPos = Param(“Maximum number of positions”,40,5,1000,1);
SetOption(“MaxOpenPositions”,MaxPos);_SECTION_END();
//******************************************************
//Account / Sizing
//******************************************************SetTradeDelays(0,0,0,0); //trade delays (in days)
SetOption(“AllowSamebarExit”,True); //exits can occur on entry days
SetOption(“AllowPositionShrinking”,False); //if on, will reduce position size if available equity is less than requested by position size
SetOption(“InterestRate”,0); //interest rate earned by funds sitting in cash
SetOption(“MinShares”,1); //minimum position size in shares
SetOption(“MinPosValue”,1); //minimum position value in dollars
SetOption(“CommissionMode”,0); //sets mode for commissions; options are:
SetOption(“ReverseSignalForcesExit”,False); //if set to true, a long position will be closed on a short entry and vice versa
SetOption(“UsePrevBarEquityForPosSizing”,True);
PositionScore = mtRandom();//******************************************************
//Filter
//******************************************************Filter = LE;
AddColumn(LE,”LE”,1);April 19, 2017 at 11:17 pm #106663JulianCohenParticipantOutstanding Brent.
Thanks a lot
April 20, 2017 at 12:31 am #106664LeeDanelloParticipantThat’s going straight to the pool room
-
AuthorPosts
- You must be logged in to reply to this topic.