Bruce, I really appreciate you taking the time to explain things. >From your earlier hint about the buggy MaxBuys statement, I was able to figure >out that it was allowing the system to take 1 position more than specified.
What you have said about the bo.EnterTrade makes perfect sense now. Even this AB newbie could understand it clearly! Also I have heard from a couple people through email that they would love for AmiBroker to have this functionality built in, so until it does, I think this code may make a great addition to AmiBrokerU. Thanks again Bruce. --- In [email protected], "Bruce" <bru...@...> wrote: > > Woodshedder - > > Got delayed. But, I said I would try to explain. I really was hoping > you wouldn't ask, so buckle your seat belt :-) As I mentioned, mixing > mid-level code with low-level code is generally not a good idea. Recall > that the "bar" loop that you used looked like this - > > { > CntBuys = 0; > for ( sig = bo.GetFirstSignal( i ); sig; sig = bo.GetNextSignal( i ) ) > { > if ( sig.IsEntry() ) > { > CanEnter = False; > if ( CntBuys <= MaxBuys ) > { > bo.EnterTrade( i, sig.Symbol, True, sig.Price, sig.PosSize, > sig.PosScore, > RoundLotSize = 0 ); > CanEnter = True; > CntBuys++; > } > if ( ! CanEnter ) > sig.Price = -1; > } > } > bo.ProcessTradeSignals( i ); > } > > BTW,the way that MaxBuys is constructed the statement should have been > if (CntBuys < MaxBuys) ... but that's not the real problem. The basic > problem is that the bo.EnterTrade call will generate additional trades > if redundant buy signals exist along with certain sell signal positions > because it is operating IN ADDITION TO the bo.ProcessSignals() call. > You have not posted your signal code so I can not tell you what in > particular is problematic. So let's just assume it happens, then I'll > give an example that hopefully has a coding nugget also. > > If redundant signals exist, bo.EnterTrade is going to do exactly what > you tell it - whether"multi" is set or not. If you are already in a > trade for that ticker,it will enter a second position. It should be > straightforward to see that this will change the equity result in your > case. > > Regarding redundant signals, I'll offer an example of how it can happen > when you don't expect it. Consider this construct - > > Buy = Cross( C, MA( C, 5 ) ); > Sell = Cross( MA( C, 5 ), C ); > > At first blush, it looks like it can't generate redundant signals. > Cross yields a 1 then the difference between the two arguments goes > from<= 0 to > 0. But, consider this sequence. Price goes above MA,then > retreats to EXACTLY the MA, then goes up. You would get two buys. > Normally this doesn't happen because price is 2 decimal places and the > MA has greater precision. But, with dividend adjusted data, such as > funds that have more decimal digits, it CAN and DOES happen. > > Bottom line is that bo.EnterTrade can force multiple trades without > the"multi" backtest mode. It is doing what you told it to because in > using the low-level CBT, you are taking control. > > So, I just suggested commenting out the low-level code and letting the > CBT run in mid-level mode and be subject the backtest mode that you had > set. > > I hope that explains everything well enough for now. I'll explore > aspects of the CBT and some debugging techniques in the future on > AmibrokerU. > > -- BruceR > > > > > --- In [email protected], "woodshedder_blogspot" > <woodshedder_blogspot@> wrote: > > > > Thanks Bruce! By commenting out the bo.EnterTrade call, results match > the results not using the combo low/med level code. > > > > If it is not too much trouble, I would like to know the reason behind > why it is now working. > > > > And finally, it should now work to limit new buys per day, no? > > > > Again, thanks! > > > > --- In [email protected], "Bruce" brucer@ wrote: > > > > > > Woodshedder, TA - > > > > > > Looked like an interesting puzzle and I took a look at it over a cup > of > > > coffee (actually it took 2 cups). Thought it might make a good > example > > > for AmibrokerU, but probably not. BTW, kudos to Woodsheeder for > sticking > > > with it as a new user. > > > > > > Anyway, my first reaction when I saw the mixing of mid-level and > > > low-level CBT code was - in general, probably not a good idea. > There > > > can be some subtle issues. There is also a very minor bug with > MaxBuys, > > > but it has no effect. > > > > > > As TA said, it can be tough to tell without your code and your > settings. > > > But, I think that the easiest way to make the results match the 10 > > > position test that Woodshedder mentions is to do the following (I > know > > > it may seem odd) - > > > > > > Comment out the bo.EnterTrade() call. > > > > > > Now, if that works and you don't need to know the explanation of > what I > > > think might be the problem, stop here. > > > > > > -- BruceR > > > > > > > > > > > > --- In [email protected], "woodshedder_blogspot" > > > <woodshedder_blogspot@> wrote: > > > > > > > > TA, no doubt it works in RegularRaw2. I completely agree. I'm just > > > confused now as to what is happening when I change the mode to > Regular. > > > > Thanks! > > > > > > > > --- In [email protected], "ta" tagroups@ wrote: > > > > > > > > > > Not seeing your setting it is difficult to see why your results > > > don't match. > > > > > I know the code that I gave you works. I have tested it > extensively. > > > TA > > > > > > > > > > > > > > > > > > > > From: [email protected] > [mailto:[email protected]] > > > On Behalf > > > > > Of woodshedder_blogspot > > > > > Sent: Tuesday, September 29, 2009 7:28 PM > > > > > To: [email protected] > > > > > Subject: [amibroker] Re: Help Limiting number of positions added > per > > > day > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > TA Quant, and anyone else, I figured out why the code was taking > so > > > long to > > > > > run. It is because the setbacktestmode was set to RegularRaw2. > When > > > I set it > > > > > to RegularRaw, it runs as normal, and removes redundant signals > > > (which I > > > > > want). > > > > > > > > > > However, if I set the code to allow 10 max buys a day, the > results > > > do not > > > > > match results generated without the custom backtester code, when > I > > > just use > > > > > a max of 10 positions. It seems that it should be the same as 10 > max > > > buys a > > > > > day should be the same as allowing a maximum of 10 positions but > not > > > > > limiting the number of new positions allowed at one time. > > > > > > > > > > I've included the code below, as suggested by TA. Thanks for any > > > help with > > > > > this! > > > > > > > > > > MaxBuys = 5; > > > > > SetBacktestMode( backtestRegular ); > > > > > SetCustomBacktestProc(""); > > > > > if ( Status( "action" ) == actionPortfolio ) > > > > > { > > > > > bo = GetBacktesterObject(); > > > > > bo.PreProcess(); > > > > > for ( i = 0; i < BarCount; i++ ) > > > > > { > > > > > CntBuys = 0; > > > > > for ( sig = bo.GetFirstSignal( i ); sig; sig = bo.GetNextSignal( > i ) > > > ) > > > > > { > > > > > if ( sig.IsEntry() ) > > > > > { > > > > > // this handles limiting of number of order per day > > > > > CanEnter = False; > > > > > if ( CntBuys <= MaxBuys ) > > > > > { > > > > > bo.EnterTrade( i, sig.Symbol, True, sig.Price, sig.PosSize, > > > sig.PosScore, > > > > > RoundLotSize = 10); > > > > > CanEnter = True; > > > > > CntBuys++; > > > > > } > > > > > if ( ! CanEnter ) sig.Price = -1; > > > > > } > > > > > } > > > > > bo.ProcessTradeSignals( i ); > > > > > } > > > > > bo.PostProcess(); > > > > > } > > > > > > > > > > --- In [email protected] > > > <mailto:amibroker%40yahoogroups.com> , > > > > > "woodshedder_blogspot" <woodshedder_blogspot@> wrote: > > > > > > > > > > > > Yes, you're right, it eventually finishes the report. I'm > looking > > > back > > > > > about 3 years right now, which is 670 trades, and it has taken > it > > > over 5 > > > > > minutes, but it finishes. > > > > > > > > > > > > This is exactly what I've been looking for, so again,I really > > > appreciate > > > > > the help. > > > > > > --- In [email protected] > > > <mailto:amibroker%40yahoogroups.com> , > > > > > "ta" <tagroups@> wrote: > > > > > > > > > > > > > > I think it has to do with number traders/signals that your > > > system > > > > > generate. > > > > > > > I have tested it over ten years with a system that generates > > > about 2000 > > > > > > > trades. It takes about 3 minutes. I don't think that AA is > > > unresponsive. > > > > > I > > > > > > > think it is processing the signals. Let go I am sure it will > > > finish. > > > > > > > > > > > > > > > > > > > > > > > > > > > > From: [email protected] > > > <mailto:amibroker%40yahoogroups.com> > > > > > [mailto:[email protected] > > > <mailto:amibroker%40yahoogroups.com> ] On > > > > > Behalf > > > > > > > Of woodshedder_blogspot > > > > > > > Sent: Sunday, September 27, 2009 9:52 PM > > > > > > > To: [email protected] > > > <mailto:amibroker%40yahoogroups.com> > > > > > > > Subject: [amibroker] Re: Help Limiting number of positions > added > > > per day > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Yes, that code is working. Thanks TA! > > > > > > > > > > > > > > Is it normal though for it cause the AA window to go > > > non-responsive when > > > > > > > backtesting a range of more than 1 year? > > > > > > > > > > > > > > I can test over 9 months and it works-with about a minute > delay > > > between > > > > > the > > > > > > > backtest finishing and the report being generated. > > > > > > > > > > > > > > If I test over much more than 9 months, it never generates > the > > > report- > > > > > > > instead it just seems to keep processing something. > > > > > > > > > > > > > > Thanks! > > > > > > > > > > > > > > --- In [email protected] > > > <mailto:amibroker%40yahoogroups.com> > > > > > <mailto:amibroker%40yahoogroups.com> , "ta" > > > > > > > <tagroups@> wrote: > > > > > > > > > > > > > > > > Since you have not posted your code I can not debug it for > you > > > but the > > > > > > > > following code works for me: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > MaxBuys = 5; > > > > > > > > SetBacktestMode( backtestRegularRaw2 ); > > > > > > > > SetCustomBacktestProc(""); > > > > > > > > if ( Status( "action" ) == actionPortfolio ) > > > > > > > > { > > > > > > > > bo = GetBacktesterObject(); > > > > > > > > bo.PreProcess(); > > > > > > > > for ( i = 0; i < BarCount; i++ ) > > > > > > > > { > > > > > > > > cntBuys = 0; > > > > > > > > for ( sig = bo.GetFirstSignal( i ); sig; sig = > > > bo.GetNextSignal( i ) ) > > > > > > > > > > > > > > > > { > > > > > > > > if ( sig.IsEntry() ) > > > > > > > > { > > > > > > > > // this handles limiting of number of order per day > > > > > > > > CanEnter = False; > > > > > > > > if ( CntBuys <= MaxBuys ) > > > > > > > > { > > > > > > > > bo.EnterTrade( i, sig.Symbol, True, sig.Price, > sig.PosSize, > > > > > > > > sig.PosScore, RoundLotSize = 1); > > > > > > > > CanEnter = True; > > > > > > > > CntBuys++; > > > > > > > > } > > > > > > > > if ( ! CanEnter ) sig.Price = -1; > > > > > > > > } > > > > > > > > } > > > > > > > > bo.ProcessTradeSignals( i ); > > > > > > > > } > > > > > > > > bo.PostProcess(); > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > From: [email protected] > > > <mailto:amibroker%40yahoogroups.com> > > > > > <mailto:amibroker%40yahoogroups.com> > > > > > > > [mailto:[email protected] > > > <mailto:amibroker%40yahoogroups.com> > > > > > <mailto:amibroker%40yahoogroups.com> ] On > > > > > > > Behalf > > > > > > > > Of woodshedder_blogspot > > > > > > > > Sent: Saturday, September 26, 2009 3:52 PM > > > > > > > > To: [email protected] > > > <mailto:amibroker%40yahoogroups.com> > > > > > <mailto:amibroker%40yahoogroups.com> > > > > > > > > Subject: [amibroker] Re: Help Limiting number of positions > > > added per > > > > > day > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > TA, thanks for the help. > > > > > > > > I'm having a problem with this line: > > > > > > > > bo.PostProcess(); > > > > > > > > > > > > > > > > This is the error I'm getting: "Error 18 COM object > variable > > > is not > > > > > > > > initialized or has invalid type (valid COM object handle > > > required) > > > > > > > > > > > > > > > > Wood > > > > > > > > > > > > > > > > --- In [email protected] > > > <mailto:amibroker%40yahoogroups.com> > > > > > <mailto:amibroker%40yahoogroups.com> > > > > > > > <mailto:amibroker%40yahoogroups.com> , "ta" > > > > > > > > <tagroups@> wrote: > > > > > > > > > > > > > > > > > > You need to use Custom Backtester as follows: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > MaxBuys = 5; > > > > > > > > > > > > > > > > > > SetBacktestMode( backtestRegularRaw2 ); > > > > > > > > > > > > > > > > > > SetCustomBacktestProc(""); > > > > > > > > > > > > > > > > > > if ( Status( "action" ) == actionPortfolio ) > > > > > > > > > > > > > > > > > > { > > > > > > > > > > > > > > > > > > bo = GetBacktesterObject(); > > > > > > > > > > > > > > > > > > bo.PreProcess(); > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > for ( sig = bo.GetFirstSignal( i ); sig; sig = > > > > > > > > > bo.GetNextSignal( i ) ) > > > > > > > > > > > > > > > > > > { > > > > > > > > > > > > > > > > > > if ( sig.IsEntry() ) > > > > > > > > > > > > > > > > > > { > > > > > > > > > > > > > > > > > > // this handles limiting of number of order > > > > > > > > > per day > > > > > > > > > > > > > > > > > > CanEnter = False; > > > > > > > > > > > > > > > > > > if ( CntBuys <= MaxBuys ) > > > > > > > > > > > > > > > > > > { > > > > > > > > > > > > > > > > > > > > > > > > > > > bo.EnterTrade( i, sig.Symbol, True, sig.Price, > sig.PosSize, > > > > > > > sig.PosScore, > > > > > > > > > RoundLotSize = 1); > > > > > > > > > > > > > > > > > > CanEnter = > > > > > > > > > True; > > > > > > > > > > > > > > > > > > CntBuys++; > > > > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > if ( ! CanEnter ) > > > > > > > > > > > > > > > > > > sig.Price = > > > > > > > > > -1; > > > > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > bo.ProcessTradeSignals( i ); > > > > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > bo.PostProcess(); > > > > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > From: [email protected] > > > <mailto:amibroker%40yahoogroups.com> > > > > > <mailto:amibroker%40yahoogroups.com> > > > > > > > <mailto:amibroker%40yahoogroups.com> > > > > > > > > [mailto:[email protected] > > > <mailto:amibroker%40yahoogroups.com> > > > > > <mailto:amibroker%40yahoogroups.com> > > > > > > > <mailto:amibroker%40yahoogroups.com> ] On > > > > > > > > Behalf > > > > > > > > > Of woodshedder_blogspot > > > > > > > > > Sent: Thursday, September 24, 2009 8:25 PM > > > > > > > > > To: [email protected] > > > <mailto:amibroker%40yahoogroups.com> > > > > > <mailto:amibroker%40yahoogroups.com> > > > > > > > <mailto:amibroker%40yahoogroups.com> > > > > > > > > > Subject: [amibroker] Help Limiting number of positions > added > > > per day > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Greetings group. > > > > > > > > > > > > > > > > > > I want to limit the number of positions a system will > take > > > on any > > > > > given > > > > > > > > day. > > > > > > > > > > > > > > > > > > > > > > > > > > > For example, if a system can handle 20 max positions, I > > > would like > > > > > it to > > > > > > > > > only take on 5 new positions a day (assuming there are > more > > > than 5 > > > > > valid > > > > > > > > > signals per day) until it arrives at 20 positions, > rather > > > than > > > > > taking on > > > > > > > > all > > > > > > > > > available positions on day 1. > > > > > > > > > > > > > > > > > > Thanks for your help. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >
