the code is correct. Small difference in the amount of multiples of the commission due to a lesser number of trades when systems are combined.
I got a bigger difference that kept me busy for a while but found this: @TFS# requested size is greater than 10 % of the bar volume. Limit applied. @TFS# not entered because requested size is less than MinShares/MinPosValue this happened in the combined system only on a day the markets are closed but still futures are traded for a few hours. So the combined system rejected the trade while the individual system took it. I did not filter these days out. But I checked a couple of months week after week and the only difference I get are multiples of the commission, regards, Ed From: Edward Pottasch Sent: Wednesday, July 28, 2010 11:14 AM To: [email protected] Subject: Re: [amibroker] Re: question for Custom Backter specialists [1 Attachment] [Attachment(s) from Edward Pottasch included below] hi, it required some empirical computing but it seems to work now. Or at least in the detailed trade log the proper positions and position sizes are taken and also the equity curve of the combined systems is close to the result I get when I add the individual systems but not exactly. I am checking out now why I get a small difference between the combined backtest result and the sum of the individual backtests. 1 thing I found is that when combining the systems the total number of trades made during the day is sometimes smaller then when you would run the systems separately. This is 1 cause I get a small difference. But there seems to be another thing, which I still have to figure out, but seems to have something to do with how Amibroker charges for commissions when scaling is involved. Checking day by day now but for who is interested I attached the code: this code combines 3 test systems. CBT code is used to correct position sizes. It is therefor example code how one could combine multiple systems into 1 system. regards, Ed From: Bruce Sent: Tuesday, July 27, 2010 7:29 PM To: [email protected] Subject: [amibroker] Re: question for Custom Backter specialists Ed - A SWAG on my part, but I'm guessing that you are not differentiating the passes. What I think that you need is something like. Let's say that you have the sizes in an array called size - actex = Status( "actionex" ); if ( actex == actionbacktest ) { StaticVarSet( "savedsizearray", size ); } SetOption("UseCustomBacktestProc", True); if ( actex == actionportfolio ) { size = StaticVarGet( "savedsizearray" ); } If you don't isolate the StaticVarSet only on the backtest, you would get an issue something like you are describing. If you still have an issue, post back, and I'll clean up some code and post. -- Bruce --- In [email protected], "Edward Pottasch" <empotta...@...> wrote: > > hi Bruce, > > thanks for your reply. Funny that I just tried this. Writing the value into a > static variable and calling it within the CBT. Gives me a result of 0 again. > > Can you conform this or is it just me > > thanks, Ed > > > > > From: Bruce > Sent: Tuesday, July 27, 2010 6:46 PM > To: [email protected] > Subject: [amibroker] Re: question for Custom Backter specialists > > > > > > Ed - > > I was going to answer your prior question about running the portfolio > backtester from an indicator, when I saw this one. It is fairly > straightforward. > > In a backtest pass, arrays are calculated over the entire range of the data, > irrespective of the AA range (ignoring QuickAFL special cases for this > example). > > The CBT pass is run on a ticker called ~~~EQUITY which is defined for the > test with a start AND end date that corresponds to the AA range specified. > > So, by definition, the first bar in the test is 0. If you store the size info > in static arrays, you can read them in the CBT pass an the alignment will be > taken care of. > > -- Bruce > > --- In [email protected], "Edward Pottasch" <empottasch@> wrote: > > > > hi Mike, > > > > thanks for your reply. Yes I tried that. Also tried to define it as global. > > But I keep getting a value 0 when defined in or outside the CBT code. > > > > or bi_start, defined as: bi_start = > > LastValue(ValueWhen(Status("firstbarintest"),BarIndex())); > > > > whether defined inside or outside CBT code when I try to access its value > > inside the CBT code it gives me 0. Outside the CBT code I get the proper > > value. I am puzzled. Asked helpdesk but no answer (yet). Trying to solve it > > another way. > > > > regards, Ed > > > > > > > > > > > > From: Mike > > Sent: Tuesday, July 27, 2010 5:40 PM > > To: [email protected] > > Subject: [amibroker] Re: question for Custom Backter specialists > > > > > > > > Ed, > > > > Try moving the calculation of bi_start inside the CBT code. > > > > if (Status("action") == actionPortfolio) > > { > > bi_start = ...; > > } > > > > Mike > > > > --- In [email protected], "Edward Pottasch" <empottasch@> wrote: > > > > > > hi, > > > > > > I am working on code that allows for the combination of multiple systems. > > > Combining signals leads to situations that you need to cover 1 position > > > and buy 3 positions at the same bar. Therefor in high level AFL you can > > > not define the positionSize properly since it needs a separate size for > > > the cover and buy but you are only allowed to fill 1 array element in the > > > positionSize array. > > > > > > So what I did is first define the buy/sell etc arrays and then I defined > > > separate positionSize arrays, positionSizeBuy, PositionSizeSell etc. > > > > > > Then I define a dummy positionSize array so that the proper signals are > > > calculated except that in some cases the positionSize is at fault. > > > > > > Then I use the "Custom Backtester" CBT to change the positionSize, see > > > code below. > > > > > > My question: the CBT starts to loop through the bars starting at i = 0. > > > However, this index coincides with the start bar of the backtest which > > > you set in the AA window. The arrays in which I have set the positionSize > > > I calculated outside the CBT and have their index starting at the true > > > starting index of the complete data array. > > > > > > So then I calculate the index at which the backtest starts and call that > > > bi_start, using: > > > > > > bi_start = LastValue(ValueWhen(Status("firstbarintest"),bi)); > > > > > > This number I want to use inside the CBT code, for instance like: > > > positionSizeBuy[ bi_start + i ], to access the proper positionSize for a > > > certain element. > > > > > > But once inside the CBT it does not recognise bi_start, it is set to 0. > > > Why is this? > > > > > > thanks, Ed > > > > > > > > > snippet of code: > > > > > > > > > bi_start = LastValue(ValueWhen(Status("firstbarintest"),bi)); > > > ""; > > > "bi_start: " + WriteVal(bi_start); > > > "barindex backtest test: " + WriteVal(bi - bi_start); > > > "BarIndex(): " + WriteVal(bi); > > > > > > // custom backtest. Replace dummy positionSize > > > SetCustomBacktestProc(""); > > > if (Status("action") == actionPortfolio) > > > { > > > > > > bo = GetBacktesterObject(); > > > bo.PreProcess(); > > > > > > for (i = 0; i < BarCount; i++) > > > { > > > > > > //_TRACE("bi_start");// + " " + bi_start[ i ]; > > > > > > for (sig = bo.GetFirstSignal(i); sig; sig = bo.GetNextSignal(i)) > > > { > > > > > > _TRACE("sig: " + sig.IsEntry() + " " + sig.IsExit() + " " + sig.IsLong() > > > + " " + sig.IsScale() + " " + i + " bi_start: " + bi_start); > > > > > > // buy -1,0,-1,0 > > > if (sig.IsEntry() AND !sig.IsExit() AND sig.IsLong() AND !sig.IsScale()) > > > { > > > //_TRACE("Buy" + i); > > > sig.PosSize = positionSizeBuy[ bi_start + i ]; > > > } > > > // short -1,0,0,0 > > > else if (sig.IsEntry() AND !sig.IsExit() AND !sig.IsLong() AND > > > !sig.IsScale()) > > > { > > > //_TRACE("Short" + i); > > > sig.PosSize = positionSizeShort[ bi_start + i ]; > > > } > > > // ScaleIn (long or short) 0,0,-1,-1 > > > else if (!sig.IsEntry() AND !sig.IsExit() AND sig.IsLong() AND > > > sig.IsScale()) > > > { > > > //_TRACE("ScaleIn Long/Short" + i); > > > sig.PosSize = Max(positionSizeBuy[ bi_start + i ],positionSizeShort[ > > > bi_start + i ]); > > > } > > > // sell 0,-1,-1,0 > > > else if (!sig.IsEntry() AND sig.IsExit() AND sig.IsLong() AND > > > !sig.IsScale()) > > > { > > > //_TRACE("Sell" + i); > > > sig.PosSize = positionSizeSell[ bi_start + i ]; > > > } > > > // cover 0,-1,0,0 > > > else if (!sig.IsEntry() AND sig.IsExit() AND !sig.IsLong() AND > > > !sig.IsScale()) > > > { > > > //_TRACE("Cover" + i); > > > sig.PosSize = positionSizeCover[ bi_start + i ]; > > > } > > > // ScaleOut (long or short) 0,0,0,-1 > > > else if (!sig.IsEntry() AND !sig.IsExit() AND !sig.IsLong() AND > > > sig.IsScale()) > > > { > > > //_TRACE("ScaleOut Long/Short" + i); > > > sig.PosSize = Max(positionSizeBuy[ bi_start + i ],positionSizeShort[ > > > bi_start + i ]); > > > } > > > } > > > bo.ProcessTradeSignals(i); > > > } > > > bo.PostProcess(); > > > } > > > > > >
