[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [amibroker] Re: How do I backtest placing a restricted number of limit orders each night?



PureBytes Links

Trading Reference Links

Hello,

> Thank you for the code sample. Unfortunately, AmiBroker will force 
> the BuyPrice to be between Low and High for that bar.

You can switch this default behaviour off using:

http://www.amibroker.com/f?setoption

SetOption("PriceBoundChecking", False );


Best regards,
Tomasz Janeczko
amibroker.com
----- Original Message ----- 
From: "Mike" <sfclimbers@xxxxxxxxx>
To: <amibroker@xxxxxxxxxxxxxxx>
Sent: Wednesday, September 05, 2007 9:38 AM
Subject: [amibroker] Re: How do I backtest placing a restricted number of limit orders each night?


> Tomasz,
> 
> Thank you for the code sample. Unfortunately, AmiBroker will force 
> the BuyPrice to be between Low and High for that bar. Therefore the 
> logic at:
> 
>  BuyPrice = Ref(Close, -1) * 0.95;
> 
> will fail whenever the limit price was not reached. Instead of 
> holding the desired limit price (lower than the Low), AmiBroker will 
> force the value to Low. As a result, the custom backtester logic:
> 
>  if( sig.Price < LowPrice[ bar ] ) {
> 
> will never be true, and false buys will never be cancelled.
> 
> We can store the limit price in another array instead, such as 
> PositionSize. But, then we must add code to change the PositionSize 
> back to a valid value within the custom backtester.
> 
> So, it looks like with some changes, your code sample would do the 
> job. But it requires changing the logic of the strategy (e.g. change 
> Buy signal to ignore limit price up front, store limit price in 
> another array like PositionSize), which is what I was trying to avoid.
> 
> The code that I posted earlier is heavy, but it appears to work 
> without needing any changes to the strategy logic.
> 
> At this point, I guess it boils down to a preference issue.
> 
> Thanks,
> 
> Mike
> 
> --- In amibroker@xxxxxxxxxxxxxxx, "Tomasz Janeczko" <groups@xxx> 
> wrote:
>>
>> Mike,
>> 
>> I am not sure where you see any problem. Whenever the margin is 
> enough to handle the problem or
>> not depends on your broker and their policies. Some are more 
> flexible than others.
>> My systems don't generate that many signals each bar, but if your 
> system generates so many signals
>> and you need to place limit orders for way more than your broker 
> margin account would allow,
>> you can simulate "reserving" process in custom backtester,
>> and it seems that you have already done that. 
>> 
>> If you are asking if I have easier method - yes I have. My code is 
> shorter and is quite simple actually
>> - I am just checking limit orders inside CB and reduce available 
> cash for that particular bar
>> and then re-add it after signals are processed
>> 
>> setup = .... 
>> BuyPrice = Ref(Close, -1) * 0.95; // store limit price 
> unconditionally 
>> Buy = Ref(setup, -1); // don't put price penetration condition 
> here - will be handled in CB 
>> Sell = .... 
>> /* 
>> */ 
>> SetCustomBacktestProc(""); 
>> 
>> if (Status("action") == actionPortfolio) 
>> { 
>>   bo = GetBacktesterObject(); 
>>   bo.PreProcess(); 
>> 
>>   for (bar = 0; bar < BarCount; bar++) 
>>   { 
>>     ReserveCash = 0; 
>> 
>>     for (sig = bo.GetFirstSignal(bar); 
>>          sig; 
>>          sig = bo.GetNextSignal(bar)) 
>>     { 
>>       if (sig.IsEntry() AND 
>>           sig.IsLong() ) 
>>       {   
>>          LowPrice = Foreign( sig.Symbol, "L" ); 
>> 
>>          if( sig.Price < LowPrice[ bar ] ) 
>>          { 
>>            // trade is NOT entered because limit is not reached 
>>            if( sig.PosSize > 0 ) PosValue = sig.PosSize; 
>>            else PosValue = bo.Equity * -0.01 * sig.PosSize; 
>> 
>>            ReserveCash = ReserveCash + PosValue; 
>>            bo.Cash = bo.Cash - PosValue; // subtract from available 
> cash 
>> 
>>            sig.Price = -1; // this marks the signal to be skipped 
>>          } 
>>        } 
>>      } 
>>        
>>      bo.ProcessTradeSignals(bar); 
>> 
>>      bo.Cash = bo.Cash + ReserveCash; // add the reserved cash back 
>>   } 
>> 
>>   bo.PostProcess(); 
>> }
>> 
>> 
>> Best regards,
>> Tomasz Janeczko
>> amibroker.com
>> 
>> ----- Original Message ----- 
>> From: "Mike" <sfclimbers@xxx>
>> To: <amibroker@xxxxxxxxxxxxxxx>
>> Sent: Wednesday, September 05, 2007 1:04 AM
>> Subject: [amibroker] Re: How do I backtest placing a restricted 
> number of limit orders each night?
>> 
>> 
>> > Just a quick correction to my previous reply. I have received as 
> many 
>> > as 60 "setups" in one night, not all of which result in 
>> > AmiBroker "signals" on the next trading day (due to limit order 
> not 
>> > being reached).
>> > 
>> > Similarly, I meant to say that expanding the one position 
> example, 
>> > you will hit the same problem as soon as you have more "setups" 
> than 
>> > available funds.
>> > 
>> > Sorry for any confusion.
>> > 
>> > --- In amibroker@xxxxxxxxxxxxxxx, "Mike" <sfclimbers@> wrote:
>> >>
>> >> Tomasz,
>> >> 
>> >> Thank you for your continued replies.
>> >> 
>> >> I am trading in a REAL account in REAL life with 50% margin. 
> Some 
>> >> nights I get few signals, other nights I get many. I trade over 
>> > 7000 
>> >> symbols accross NYSE, NASDAQ, and AMEX. I have had as many as 60 
>> >> signals in one night. Even using all available margin, there are 
>> >> sometimes not enough funds to cover the orders.
>> >> 
>> >> Saying that your strategies do not encounter the problem does 
> not 
>> >> imply that the problem does not exist.
>> >> 
>> >> I gave a simplistic one order example just to illustrate the 
> point. 
>> >> Now that you understand the scenario, expand the example to a 10 
>> >> position account using any amount of margin and you hit the 
> exact 
>> >> same issue as soon as you have more signals than available funds.
>> >> 
>> >> Even using the simplistic one position example, I believe that 
> the 
>> >> backtester would still THINK that there were enough funds 
> available 
>> >> to fill the BB signal since it IGNORES funds allocated to the AA 
>> >> order that did not result in a signal. So, I think that your 
>> > comment 
>> >> does not apply here and BB would in fact get filled.
>> >> 
>> >> The underlying problem is that AmiBroker does not appear to have 
> a 
>> >> way to model the fact that the broker will commit funds to 
> orders 
>> >> *placed*, even if those orders do not get *filled*. If I am not 
>> >> mistaken, AmiBroker only considers funds commited to a *filled* 
>> > order 
>> >> (i.e. a signal).
>> >> 
>> >> There are at least 3 other forum members that have written about 
>> > this 
>> >> issue, so the scenario is real.
>> >> 
>> >> Based on my experiments so far, my code will correctly model the 
>> >> scenario described. I was hoping for either A) a better 
> solution, 
>> > or 
>> >> B) validation that the code works for others.
>> >> 
>> >> Thanks,
>> >> 
>> >> Mike
>> >> 
>> >> --- In amibroker@xxxxxxxxxxxxxxx, "Tomasz Janeczko" <groups@> 
>> >> wrote:
>> >> >
>> >> > I disagree completely.
>> >> > I am trading on REAL margin account in REAL life. With 50% 
> margin 
>> >> account
>> >> > I am always able to place limit orders for all signals I am 
>> > getting.
>> >> > 
>> >> > As to "cleaner" solution to theoretical example that you have 
>> >> provided:
>> >> > it is as easy as setting "MaxOpenPositions" to ONE.
>> >> > 
>> >> > You would end up with no position open on Tuesday night (your 
>> >> desired behaviour)  because backtester
>> >> > STOPS opening positions if "top" signal can not enter due to 
> lack 
>> >> of funds.
>> >> > 
>> >> > Best regards,
>> >> > Tomasz Janeczko
>> >> > amibroker.com
>> >> > ----- Original Message ----- 
>> >> > From: "Mike" <sfclimbers@>
>> >> > To: <amibroker@xxxxxxxxxxxxxxx>
>> >> > Sent: Tuesday, September 04, 2007 9:11 PM
>> >> > Subject: [amibroker] Re: How do I backtest placing a 
> restricted 
>> >> number of limit orders each night?
>> >> > 
>> >> > 
>> >> > > Tomasz,
>> >> > > 
>> >> > > 1. Margin does not solve the problem, it just delays it. As 
>> > soon 
>> >> as 
>> >> > > you get one too many setups you hit the same problem again. 
>> > Also, 
>> >> for 
>> >> > > aggressive strategies using full margin, margin will already 
>> > have 
>> >> > > been accounted for when placing the first 10 orders of my 
>> > example.
>> >> > > 
>> >> > > 2. When using a cash account you are not "DONE". Your code 
> will 
>> >> > > accept the top ten *SIGNALS*. The problem is that the trader 
>> > can 
>> >> not 
>> >> > > afford to place all the *ORDERS*. Your system will accept 
>> > signals 
>> >> for 
>> >> > > orders that were *NEVER PLACED*.
>> >> > > 
>> >> > > To make this as simple as possible:
>> >> > > 
>> >> > > Monday day:
>> >> > > - Have $5,000 available cash
>> >> > > - Receive entry setup for AA, BB, CC
>> >> > > - PositionScore for AA > BB > CC
>> >> > > 
>> >> > > Monday night:
>> >> > > - Place Tuesday limit order for $5,000 AA (since highest 
> score)
>> >> > > - Have $0 available cash (broker immediately *reserved* 
> $5,000 
>> >> for AA)
>> >> > > - Can *not* afford to place limit order for BB, CC
>> >> > > 
>> >> > > Tuesday day:
>> >> > > - Limit order for AA *not* met
>> >> > > - Limit for BB *would* have been met, but order was *not* 
> placed
>> >> > > - Limit for CC *would* have been met, but order was *not* 
> placed
>> >> > > 
>> >> > > Tuesday night (YOUR CODE):
>> >> > > - Holding $5,000 of BB  <--- Wrong!
>> >> > > - $0 available cash     <--- Wrong!
>> >> > > 
>> >> > > Tuesday night (REAL LIFE):
>> >> > > - No holdings           <--- Correct
>> >> > > - $5,000 available cash <--- Correct
>> >> > > 
>> >> > > In your code, I would be filled for $5,000 of BB which *I 
> never 
>> >> > > placed an order for*. Your code correctly determined that 
> there 
>> >> was 
>> >> > > only room to buy 1 position (e.g. did not also buy CC), but 
> it 
>> >> used 
>> >> > > funds that were *not available*. All funds were already used 
> up 
>> >> by 
>> >> > > the limit order placed for AA, so the signal for BB was 
>> >> impossible.
>> >> > > 
>> >> > > In my code, the signals for BB and CC would be cancelled 
> since 
>> >> their 
>> >> > > PositionScores are *less* than the top PositionScore (AA) 
> and I 
>> >> only 
>> >> > > had room to place 1 order, regardless of the fact that AA 
> was 
>> >> never 
>> >> > > filled. The system now correctly shows that there was no 
>> > *valid* 
>> >> > > signal for BB and CC.
>> >> > > 
>> >> > > If you have a cleaner way to model this behavior, I would 
> very 
>> >> much 
>> >> > > like to use it.
>> >> > > 
>> >> > > Thanks,
>> >> > > 
>> >> > > Mike
>> >> > > 
>> >> > > --- In amibroker@xxxxxxxxxxxxxxx, "Tomasz Janeczko" 
> <groups@> 
>> >> > > wrote:
>> >> > >>
>> >> > >> Hello,
>> >> > >> 
>> >> > >> In addition to the fact that if you are using MARGIN 
> account 
>> >> this 
>> >> > > is not a problem to place
>> >> > >> 15 orders because they will all be within your buying power 
>> >> > > (including margin),
>> >> > >> there is one more thing:
>> >> > >> if you are using cash account that does not allow buying 
> power 
>> >> 
>> >> > > cash
>> >> > >> the problem you are describing is non-existing. Just define
>> >> > >> SetOption("MaxOpenPositions", 10 ) 
>> >> > >> and you are DONE. The code will accept only TEN TOP entry 
>> >> signals 
>> >> > > and nothing more.
>> >> > >> (And instead of "exploration", you should use "Add 
> artificial 
>> >> > > future bar" in the settings and run BACKTEST
>> >> > >> with  TOMMORROWS date to find out signals for tommorrow).
>> >> > >> 
>> >> > >> Best regards,
>> >> > >> Tomasz Janeczko
>> >> > >> amibroker.com
>> >> > >> ----- Original Message ----- 
>> >> > >> From: "Mike" <sfclimbers@>
>> >> > >> To: <amibroker@xxxxxxxxxxxxxxx>
>> >> > >> Sent: Tuesday, September 04, 2007 7:00 PM
>> >> > >> Subject: [amibroker] Re: How do I backtest placing a 
>> > restricted 
>> >> > > number of limit orders each night?
>> >> > >> 
>> >> > >> 
>> >> > >> > Tomasz,
>> >> > >> > 
>> >> > >> > You are missing the problem.
>> >> > >> > 
>> >> > >> > Yes, setting a limit order is easy. The problem is that 
> in 
>> >> real 
>> >> > > life 
>> >> > >> > the broker will *reserve the funds* necessary to fill a 
>> > limit 
>> >> > > order 
>> >> > >> > *at the time that the order is placed*, even if the order 
> is 
>> >> > > never 
>> >> > >> > filled. If the limit is not reached, the funds will only 
>> >> become 
>> >> > >> > available again *after* the close of the bar.
>> >> > >> > 
>> >> > >> > Using portfolio constraints, the sample that you have 
>> > provided 
>> >> > > can be 
>> >> > >> > made to ensure that only 10 orders are *filled*. But, it 
>> >> assumes 
>> >> > > that 
>> >> > >> > limit orders were *placed* for all setups. That is not 
>> >> realistic.
>> >> > >> > 
>> >> > >> > So, if I have $50,000, I can only place 10 limit orders 
> of 
>> >> $5,000 
>> >> > >> > each. If I receive more than 10 setups from the previous 
>> > bar, 
>> >> > > then I 
>> >> > >> > do not have enough funds to place orders for all of them 
> and 
>> >> must 
>> >> > >> > choose the top 10 of 15.
>> >> > >> > 
>> >> > >> > Since we can only place *some* limit orders, the trading 
>> >> system 
>> >> > > must 
>> >> > >> > recognize *which* limit orders were placed, and ignore 
> the 
>> >> rest.
>> >> > >> > 
>> >> > >> > To repeat, if I have only placed limit orders for the top 
> 10 
>> >> > > setups, 
>> >> > >> > then if the limit is not reached for any of those 10, I 
> will 
>> >> have 
>> >> > > 0 
>> >> > >> > positions filled. The price action of the remaining 5 is 
>> >> > >> > irrelevant. I could not afford to place orders on all 15, 
> so 
>> >> my 
>> >> > >> > system must reflect that any fills of the remaining 5 
> *were 
>> >> never 
>> >> > >> > placed* and must be cancelled.
>> >> > >> > 
>> >> > >> > Is there a better way to model this behavior?
>> >> > >> > 
>> >> > >> > Thanks,
>> >> > >> > 
>> >> > >> > Mike
>> >> > >> > 
>> >> > >> > --- In amibroker@xxxxxxxxxxxxxxx, "Tomasz Janeczko" 
>> > <groups@> 
>> >> > >> > wrote:
>> >> > >> >>
>> >> > >> >> Solution was provided before. It does not require any 
>> > custom 
>> >> > >> > backtest code
>> >> > >> >> and is actually easy.
>> >> > >> >> I repeat:
>> >> > >> >> 
>> >> > >> >> LimitPrice = 
>> >> > >> >> Buy = your original buy rule
>> >> > >> >> 
>> >> > >> >> SetTradeDelays( 0, 0, 0, 0 ); // we use zero delays but 
> we 
>> >> use 
>> >> > > Ref
>> >> > >> > () to shift buy signal.
>> >> > >> >> 
>> >> > >> >> Buy = Ref( Buy, -1 ) AND Low < LimitPrice; // this 
> handles 
>> >> LIMIT 
>> >> > >> > order
>> >> > >> >> BuyPrice = Min( Open, LimitPrice ); // this ensures 
>> >> limitprice 
>> >> > > is 
>> >> > >> > used for entry or the Open price if it is lower than limit
>> >> > >> >> 
>> >> > >> >> SetBacktestMode( backtestRegularRaw ); // this makes 
> sure 
>> >> that 
>> >> > >> > repeated signals occuring on many bars in sequence are 
> not 
>> >> ignored
>> >> > >> >> 
>> >> > >> >> 
>> >> > >> >> You don't need to do anything as convoluted as you are 
>> >> > > apparently 
>> >> > >> > doing in your formula
>> >> > >> >> as the code ABOVE handles placing limit orders (which 
> are 
>> >> only 
>> >> > >> > executed if
>> >> > >> >> price penetrates your desired limit level).
>> >> > >> >> 
>> >> > >> >> Best regards,
>> >> > >> >> Tomasz Janeczko
>> >> > >> >> amibroker.com
>> >> > >> >> ----- Original Message ----- 
>> >> > >> >> From: "Mike" <sfclimbers@>
>> >> > >> >> To: <amibroker@xxxxxxxxxxxxxxx>
>> >> > >> >> Sent: Tuesday, September 04, 2007 9:08 AM
>> >> > >> >> Subject: [amibroker] Re: How do I backtest placing a 
>> >> restricted 
>> >> > >> > number of limit orders each night?
>> >> > >> >> 
>> >> > >> >> 
>> >> > >> >> > Hi, I am submitting the following code for comment. I 
>> >> believe 
>> >> > >> > that I 
>> >> > >> >> > have a generic solution for the "fixed number of 
>> >> conditional 
>> >> > >> > orders 
>> >> > >> >> > on next bar" problem.
>> >> > >> >> > 
>> >> > >> >> > Constructive criticism is welcomed. Please feel free 
> to 
>> >> point 
>> >> > > out 
>> >> > >> > any 
>> >> > >> >> > bugs, inefficiencies, suggested enhancements, etc.
>> >> > >> >> > 
>> >> > >> >> > If this is deemed valuable, I can clean up the 
> formatting 
>> >> and 
>> >> > > add 
>> >> > >> > it 
>> >> > >> >> > to the files section.
>> >> > >> >> > 
>> >> > >> >> > Mike
>> >> > >> >> > 
>> >> > >> >> > Problem Statement:
>> >> > >> >> > ------------------
>> >> > >> >> > Need programatic support for simulating the placement 
> of 
>> > a 
>> >> > > fixed 
>> >> > >> >> > number of prioritized *conditional* orders at the next 
>> > bar, 
>> >> in 
>> >> > >> >> > response to one or more favorable "setups" triggered 
> by 
>> > the 
>> >> > >> > current 
>> >> > >> >> > bar, and constrained by the number of positions 
> permitted 
>> >> by 
>> >> > > the 
>> >> > >> >> > strategy.
>> >> > >> >> > 
>> >> > >> >> > Example:
>> >> > >> >> > --------
>> >> > >> >> > Consider a strategy that calls for the placement of 
> limit 
>> >> > > orders 
>> >> > >> > at 
>> >> > >> >> > the next bar after recognizing one or more favorable 
>> > setups 
>> >> on 
>> >> > >> > the 
>> >> > >> >> > current bar. Assume that the strategy allows a maximum 
> of 
>> >> only 
>> >> > > 10 
>> >> > >> >> > open positions at any given time, and that the setups 
> are 
>> >> > >> > prioritized 
>> >> > >> >> > from most preferred (position 1) to least preferred 
>> >> (position 
>> >> > > 10).
>> >> > >> >> > 
>> >> > >> >> > If on the first day of the strategy 20 favorable 
> setups 
>> >> were 
>> >> > >> >> > recognized, then the strategy would call for placing 
>> > limit 
>> >> > > orders 
>> >> > >> > at 
>> >> > >> >> > the next bar for *only* the top 10 preferred setups 
>> > (since 
>> >> > > only 
>> >> > >> > 10 
>> >> > >> >> > positions are permitted and we can not know in advance 
>> >> whether 
>> >> > >> > any or 
>> >> > >> >> > all of the 10 orders would actually get filled).
>> >> > >> >> > 
>> >> > >> >> > Similarly, if at some point after starting the 
> strategy 
>> > we 
>> >> > > found 
>> >> > >> >> > ourself with 2 currently open positions and received 
> 20 
>> >> > > setups, 
>> >> > >> > we 
>> >> > >> >> > would place 8 (10 - 2 = 8) limit orders for the top 8 
>> >> > > preferred 
>> >> > >> >> > setups.
>> >> > >> >> > 
>> >> > >> >> > Complications
>> >> > >> >> > -------------
>> >> > >> >> > 1. Using PositionScore and position sizing is not 
>> >> sufficient 
>> >> > >> > since 
>> >> > >> >> > they do not recognize the allocation of funds commited 
> to 
>> >> > >> >> > *conditional* order placements that do *not* get 
> filled. 
>> >> > >> > Resulting 
>> >> > >> >> > code would typically continue to attempt to fill 
>> > allowable 
>> >> > >> > position 
>> >> > >> >> > count despite not having enough funds to cover all 
>> > possible 
>> >> > >> > setups.
>> >> > >> >> > 
>> >> > >> >> > 2. Script execution for any given symbol does not have 
>> >> access 
>> >> > > to 
>> >> > >> > the 
>> >> > >> >> > PositionScore of the remaining symbols.
>> >> > >> >> > 
>> >> > >> >> > 3. Custom backtester object does not have access to 
> the 
>> >> > >> > PositionScore 
>> >> > >> >> > of any symbol that did *not* result in a generated 
> trade 
>> >> > > signal 
>> >> > >> > (i.e. 
>> >> > >> >> > if a limit order was not met, the custom backtester 
> would 
>> >> not 
>> >> > >> > have a 
>> >> > >> >> > signal object for that conditional placement, and thus 
>> >> would 
>> >> > > not 
>> >> > >> > have 
>> >> > >> >> > access to the PositionScore of the unsuccessful order).
>> >> > >> >> > 
>> >> > >> >> > Solution
>> >> > >> >> > --------
>> >> > >> >> > 1. Generate a "composite" symbol for each allowable 
>> >> position 
>> >> > > of 
>> >> > >> > the 
>> >> > >> >> > strategy (e.g. for a strategy allowing a maximum of 10 
>> > open 
>> >> > >> >> > positions, geneare composites ~Position1, 
>> > ~Position2, ..., 
>> >> > >> >> > ~Position10).
>> >> > >> >> > 
>> >> > >> >> > 2. At each bar of each symbol, calculate a 
> PositionScore 
>> >> for 
>> >> > > any 
>> >> > >> >> > conditional order based on the recognition of a setup 
> on 
>> >> the 
>> >> > >> > previous 
>> >> > >> >> > bar (e.g. PositionScore for a limit order in response 
> to 
>> > a 
>> >> > >> > recognized 
>> >> > >> >> > setup the bar before). Note that this is a 
> PositionScore 
>> >> for 
>> >> > > the 
>> >> > >> >> > *conditional* order which *may or may not* have been 
>> >> filled. 
>> >> > > If 
>> >> > >> > no 
>> >> > >> >> > setup was recognized in the previous bar the 
>> > PositionScore 
>> >> > > would 
>> >> > >> > be 
>> >> > >> >> > zero.
>> >> > >> >> > 
>> >> > >> >> > 3. Insert, in a sorted manner, the calculated 
>> > PositionScore 
>> >> > > into 
>> >> > >> > the 
>> >> > >> >> > appropriate composite, bumping down in a chain 
> reaction 
>> > any 
>> >> > >> > current 
>> >> > >> >> > composite occupants as needed.
>> >> > >> >> > 
>> >> > >> >> > For example; if the PositionScore for the current 
> symbol 
>> > at 
>> >> > > the 
>> >> > >> >> > current bar was found to be less than the value held 
> by 
>> >> > >> > ~Position1 
>> >> > >> >> > for that bar, the comparrison would next be made 
> against 
>> >> > >> > ~Position2. 
>> >> > >> >> > If the PositionScore was found to be greater than the 
>> > value 
>> >> > > held 
>> >> > >> > by 
>> >> > >> >> > ~Position2 for that bar, then the value for that bar 
> of 
>> >> > >> > ~Position2 
>> >> > >> >> > would be replaced (bumped) by PositionScore, and the 
>> > value 
>> >> > > that 
>> >> > >> > had 
>> >> > >> >> > been in ~Position2 would be moved down to ~Position3 
> for 
>> >> that 
>> >> > >> > same 
>> >> > >> >> > bar, bumping down any value held by ~Position3 in a 
> chain 
>> >> > >> > reaction 
>> >> > >> >> > until a zero composite value was found (i.e. nothing 
> to 
>> >> bump) 
>> >> > > or 
>> >> > >> > all 
>> >> > >> >> > composites had been updated.
>> >> > >> >> > 
>> >> > >> >> > e.g. given:
>> >> > >> >> > 
>> >> > >> >> > PositionScore[x] is 99 and;
>> >> > >> >> > 
>> >> > >> >> > ~Position1[x] is 100
>> >> > >> >> > ~Position2[x] is  50
>> >> > >> >> > ~Position3[x] is  49
>> >> > >> >> > ~Position4[x] is   0
>> >> > >> >> > ...
>> >> > >> >> > ~Position10[x] is  0
>> >> > >> >> > 
>> >> > >> >> > Result after insertion would be:
>> >> > >> >> > 
>> >> > >> >> > ~Position1[x] is 100
>> >> > >> >> > ~Position2[x] is  99
>> >> > >> >> > ~Position3[x] is  50
>> >> > >> >> > ~Position4[x] is  49
>> >> > >> >> > ~Position5[x] is   0
>> >> > >> >> > ...
>> >> > >> >> > ~Position10[x] is  0
>> >> > >> >> > 
>> >> > >> >> > 4. Write custom backtester logic to calculate, at each 
>> > bar, 
>> >> > > how 
>> >> > >> > many 
>> >> > >> >> > open positions exist, and reset to 0 the PosSize of 
> any 
>> >> Signal 
>> >> > >> > whose 
>> >> > >> >> > PositionScore is *less* than the PositionScore held by 
>> > the 
>> >> N-
>> >> > > th 
>> >> > >> >> > composite, where N is calculated as max allowed 
> positions 
>> >> > > minus 
>> >> > >> > the 
>> >> > >> >> > number of currently opened positions (e.g. 10 max 
>> >> positions - 
>> >> > > 2 
>> >> > >> > open 
>> >> > >> >> > positions = composite ~Position8). This emulates not 
>> > having 
>> >> > >> > placed 
>> >> > >> >> > orders for any but the top N preferred setups.
>> >> > >> >> > 
>> >> > >> >> > 5. Leave to the native backtester all other decisions 
>> >> > > regarding 
>> >> > >> > enty 
>> >> > >> >> > into positions and tie-breaking of equal PositionScore.
>> >> > >> >> > 
>> >> > >> >> > Advantages
>> >> > >> >> > ----------
>> >> > >> >> > 1. Works generically for any conditional strategy, 
> Long 
>> > or 
>> >> > > Short*.
>> >> > >> >> > 2. Works equally well for scale-in strategies.
>> >> > >> >> > 3. Makes no assumptions regarding Buy/Sell rules.
>> >> > >> >> > 4. Does not result in any phantom/artificial trades.
>> >> > >> >> > 5. Does not generate any phantom/artificial commisions.
>> >> > >> >> > 6. Does not depend on any backtester settings "tweaks".
>> >> > >> >> > 7. PositionScore data is available at all times for 
>> >> additional 
>> >> > >> >> > analysis.
>> >> > >> >> > 
>> >> > >> >> > * Backtester logic must be custom fit to your 
> strategy, 
>> > but 
>> >> > >> >> > persistence of scores is generic to all.
>> >> > >> >> > 
>> >> > >> >> > Disadvantages
>> >> > >> >> > -------------
>> >> > >> >> > 1. Slower execution resulting from heavy looping 
> (loops N 
>> >> > > times 
>> >> > >> > more 
>> >> > >> >> > than alternative proposed in msg #113384, where N 
> equals 
>> >> > > maximum 
>> >> > >> >> > allowed positions).
>> >> > >> >> > 
>> >> > >> >> > For example; A strategy backtested 3 months over 7800+ 
>> >> symbols 
>> >> > >> > using 
>> >> > >> >> > 10 allowed positions on a 1.4Ghz laptop with 1GB RAM 
>> > takes 
>> >> > > about 
>> >> > >> > 10 
>> >> > >> >> > minutes.
>> >> > >> >> > 
>> >> > >> >> > 2. Code is more complex than alternative proposed in 
> msg 
>> >> > > #113384.
>> >> > >> >> > 
>> >> > >> >> > -----
>> >> > >> >> > ----- Sample code snippets for your review (Long only)
>> >> > >> >> > ----- I have left in _TRACE statements to see what's 
>> >> happening
>> >> > >> >> > -----
>> >> > >> >> > 
>> >> > >> >> > /*
>> >> > >> >> > * Carry fixed number of positions, equally divided.
>> >> > >> >> > */
>> >> > >> >> > maxPositions = 10;
>> >> > >> >> > PositionSize = -100/maxPositions;
>> >> > >> >> > SetOption("MaxOpenPositions", maxPositions);
>> >> > >> >> > 
>> >> > >> >> > /*
>> >> > >> >> > * Custom backtester implementation to strip out orders 
>> > that 
>> >> in
>> >> > >> >> > * reality would not have been placed due to a 
> limitation 
>> > of
>> >> > >> >> > * available capital to cover bids on all setups.
>> >> > >> >> > *
>> >> > >> >> > * Note: This implementation assumes Long positions 
> only!
>> >> > >> >> > */
>> >> > >> >> > SetCustomBacktestProc("");
>> >> > >> >> > 
>> >> > >> >> > if (Status("action") == actionPortfolio) {
>> >> > >> >> >  bo = GetBacktesterObject();
>> >> > >> >> >  bo.PreProcess();
>> >> > >> >> > 
>> >> > >> >> >  for (bar = 0; bar < BarCount; bar++) {
>> >> > >> >> >    openCount = 0;
>> >> > >> >> > 
>> >> > >> >> >    for (openPos = bo.GetFirstOpenPos();
>> >> > >> >> >         openPos;
>> >> > >> >> >         openPos = bo.GetNextOpenPos())
>> >> > >> >> >    {
>> >> > >> >> >      openCount++;
>> >> > >> >> >    }
>> >> > >> >> > 
>> >> > >> >> >    minPos = maxPositions - openCount;
>> >> > >> >> >    posScores = IIF(minPos,
>> >> > >> >> >                    Foreign("~Position" + minPos, "X", 
> 0),
>> >> > >> >> >                    9999); // Highest possible score!
>> >> > >> >> > 
>> >> > >> >> >    for (sig = bo.GetFirstSignal(bar);
>> >> > >> >> >         sig;
>> >> > >> >> >         sig = bo.GetNextSignal(bar))
>> >> > >> >> >    {
>> >> > >> >> >      if (sig.IsEntry() AND sig.IsLong()) {
>> >> > >> >> >        if (sig.PosScore < posScores[bar]) {
>> >> > >> >> >          /*_TRACE(StrFormat("Score %9.4f less than top 
> %
>> >> 1.0f 
>> >> > >> > scores 
>> >> > >> >> > of %9.4f at bar %5.0f, cancel signal for ", 
> sig.PosScore, 
>> >> > > minPos, 
>> >> > >> >> > posScores[bar], bar) + sig.Symbol);*/
>> >> > >> >> > 
>> >> > >> >> >          // Order would not have been placed, cancel 
> it 
>> > out.
>> >> > >> >> >          sig.PosSize = 0;
>> >> > >> >> >        }
>> >> > >> >> >      }
>> >> > >> >> >    }
>> >> > >> >> > 
>> >> > >> >> >    bo.ProcessTradeSignals(bar);
>> >> > >> >> >  }
>> >> > >> >> > 
>> >> > >> >> >  bo.PostProcess();
>> >> > >> >> > }
>> >> > >> >> > 
>> >> > >> >> > /*
>> >> > >> >> > * For each bar following entry setup, persist 
>> > PositionScore 
>> >> > > into 
>> >> > >> > an
>> >> > >> >> > * ordered list of Foreign symbols such that we may 
> later 
>> >> have 
>> >> > >> > access
>> >> > >> >> > * to the top scores during backtesting, regardless of 
>> >> whether 
>> >> > > a 
>> >> > >> >> > * concrete signal for the ranked symbol is actually 
>> > found. 
>> >> See 
>> >> > >> >> > * custom backtester method for filtering logic.
>> >> > >> >> > *
>> >> > >> >> > * For example; a 10 position, limit order strategy 
>> >> currently 
>> >> > >> > holding
>> >> > >> >> > * 2 positions might place limit orders for only the 
> top 8 
>> >> > > setups, 
>> >> > >> >> > * despite recognizing more than 8 candidate setups. 
> This 
>> >> > > method 
>> >> > >> >> > * would sort the PositionScore of all candidate setups 
>> > into 
>> >> 10
>> >> > >> >> > * foreign symbols, regardless of whether or not the 
> limit 
>> >> > > order 
>> >> > >> > was
>> >> > >> >> > * met. The backtester would then compare the 
>> > PositionScore 
>> >> of 
>> >> > > all
>> >> > >> >> > * filled signals (i.e. all signals of the limit price 
>> >> having 
>> >> > > been 
>> >> > >> >> > * met), and cancel out those whose score was less than 
>> > the 
>> >> top 
>> >> > > 8 
>> >> > >> >> > * scores found in the Foreign symbols (i.e. cancel out 
>> >> signals 
>> >> > >> > for 
>> >> > >> >> > * those symbols upon which, in reality, a limit order 
>> > would 
>> >> > > never 
>> >> > >> >> > * actually have been placed).
>> >> > >> >> > *
>> >> > >> >> > * Note: This implementation leaves the responsibility 
> of 
>> >> tie-
>> >> > >> >> > * breaking to the backtester, when multiple symbols 
> have 
>> >> the 
>> >> > > same 
>> >> > >> >> > * PositionScore for a limited number of available 
>> >> positions. 
>> >> > > The 
>> >> > >> >> > * symbol selected by the backtester may not be the one 
>> > for 
>> >> > > which 
>> >> > >> > an 
>> >> > >> >> > * order was actually placed in real life. But, the 
> symbol 
>> >> > >> > selected 
>> >> > >> >> > * is guaranteed to at least have an equivalent 
>> >> PositionScore. 
>> >> > > Use
>> >> > >> >> > * unique PosittionScore values, or trade in real life 
>> > using 
>> >> > > the 
>> >> > >> > same
>> >> > >> >> > * tie-breaking logic that AmiBroker uses :)
>> >> > >> >> > *
>> >> > >> >> > * Note: This implementation assumes that PositionScore 
>> > will 
>> >> be 
>> >> > >> >> > * either zero, for bars not recognized as following 
> order 
>> >> > >> > placement 
>> >> > >> >> > * criteria (i.e. no setup from previous bar), or a non 
>> > zero 
>> >> > >> > positive
>> >> > >> >> > * number, for bars where order placement criteria has 
>> > been 
>> >> > > met. To
>> >> > >> >> > * reiterate, this refers to order *placement* criteria 
>> >> (i.e. 
>> >> > >> > setup),
>> >> > >> >> > * not order *fulfillment*.
>> >> > >> >> > */
>> >> > >> >> > procedure persistScores(scores) {
>> >> > >> >> >  local maxPositions; // Max positions allowed in 
> portfolio
>> >> > >> >> >  local empty;        // Array of zeros
>> >> > >> >> >  local bar;          // Loop variable
>> >> > >> >> >  local score;        // PositionScore of bar-th bar
>> >> > >> >> >  local pos;          // Loop variable
>> >> > >> >> >  local composite;    // Name of pos-th composite
>> >> > >> >> >  local posScores;    // Scores persisted to composite
>> >> > >> >> >  local delta;        // Delta between PositionScore 
> and 
>> >> > > composite
>> >> > >> >> >  local affected;     // Flag whether any deltas were 
> added
>> >> > >> >> > 
>> >> > >> >> >  maxPositions = GetOption("MaxOpenPositions");
>> >> > >> >> >  empty = Cum(0);
>> >> > >> >> > 
>> >> > >> >> >  for (pos = 1; pos <= maxPositions; pos++) {
>> >> > >> >> >    /*_TRACE("Persist " + Name() + " to position " + 
>> > pos);*/
>> >> > >> >> >    composite = "~Position" + pos;
>> >> > >> >> >    AddToComposite(0, composite, "X", 1 + 2 + 4 + 
> 8);  // 
>> >> > >> > Initialize
>> >> > >> >> >    posScores = Foreign(composite, "X", 0);  // Do not 
>> > fill 
>> >> > > holes!
>> >> > >> >> >    delta = empty;
>> >> > >> >> >    affected = false;
>> >> > >> >> > 
>> >> > >> >> >    for (bar = 0; bar < BarCount; bar++) {
>> >> > >> >> >      if (scores[bar]) {
>> >> > >> >> >        score = scores[bar];
>> >> > >> >> > 
>> >> > >> >> >        if (score > posScores[bar]) {
>> >> > >> >> >          /*_TRACE(StrFormat("Score %9.4f bumps down 
>> >> position %
>> >> > >> > 1.0f 
>> >> > >> >> > score of %9.4f at bar %5.0f", score, pos, posScores
> [bar], 
>> >> > > bar));*/
>> >> > >> >> > 
>> >> > >> >> >          // Grab current best value and hold for next 
>> >> composite
>> >> > >> >> >          // iteratation, and calculate delta needed to 
>> > add 
>> >> to 
>> >> > >> >> >          // this composite in order to make it equal 
> new 
>> >> high 
>> >> > >> > score
>> >> > >> >> > 
>> >> > >> >> >          scores[bar] = posScores[bar];
>> >> > >> >> >          delta[bar] = score - posScores[bar];
>> >> > >> >> >          affected = true;
>> >> > >> >> >        }
>> >> > >> >> >        /*else if (posScores[bar]) _TRACE(StrFormat
> ("Score 
>> > %
>> >> > > 9.4f 
>> >> > >> >> > blocked by position %1.0f score of %9.4f at bar %
> 5.0f", 
>> >> score, 
>> >> > >> > pos, 
>> >> > >> >> > posScores[bar], bar));*/
>> >> > >> >> >      }
>> >> > >> >> >    }
>> >> > >> >> > 
>> >> > >> >> >    if (affected) {
>> >> > >> >> >      AddToComposite(delta, composite, "X", 1 + 2 + 4 + 
> 8);
>> >> > >> >> >    }
>> >> > >> >> >  }
>> >> > >> >> > 
>> >> > >> >> >  /*_TRACE("\n");*/
>> >> > >> >> > }
>> >> > >> >> > 
>> >> > >> >> > setup = ...                  // Some setup recognition 
>> > logic
>> >> > >> >> > Buy = Ref(setup, -1) AND ... // Some conditional entry 
>> > logic
>> >> > >> >> > PositionScore = IIF(Ref(setup, -1), ..., 0); // Some 
>> > score 
>> >> > > logic 
>> >> > >> > or 0
>> >> > >> >> > Sell = ...                   // Some Sell logic
>> >> > >> >> > 
>> >> > >> >> > persistScores(PositionScore);
>> >> > >> >> > 
>> >> > >> >> > /*
>> >> > >> >> > * Example of 5% dip limit conditional entry:
>> >> > >> >> > *   BuyPrice = min(Open, (Ref(Close, -1) * 0.95));
>> >> > >> >> > *   Buy = Ref(setup, -1) AND Low <= BuyPrice;
>> >> > >> >> > */
>> >> > >> >> > 
>> >> > >> >> > ------
>> >> > >> >> > ------ End code snippets
>> >> > >> >> > ------
>> >> > >> >> > 
>> >> > >> >> > --- In amibroker@xxxxxxxxxxxxxxx, "ed2000nl" 
>> > <empottasch@> 
>> >> > > wrote:
>> >> > >> >> >>
>> >> > >> >> >> i'll try to reply directly from yahoo. My posts 
> aren't 
>> >> coming 
>> >> > >> >> > through
>> >> > >> >> >> anymore. Might be because of the ISP ...
>> >> > >> >> >> 
>> >> > >> >> >> 
>> >> > >> >> >> so if I understand correctly the problem is not that 
> the 
>> >> > >> > backtester
>> >> > >> >> >> picks  20 stocks while there is only money for 10 but 
>> > you 
>> >> > > have a 
>> >> > >> >> > problem
>> >> > >> >> >> with the fact  that if the 10 actual signals are not 
>> >> filled 
>> >> > > it 
>> >> > >> > will 
>> >> > >> >> > use
>> >> > >> >> >> the lower ranking 10  signals and this is not what 
> you 
>> >> > > want.   
>> >> > >> > You 
>> >> > >> >> > can
>> >> > >> >> >> include this in the backtester. I explained the same 
>> > thing 
>> >> > > some  
>> >> > >> >> > time
>> >> > >> >> >> ago. For signals that you actually want to enter but 
> in 
>> >> real 
>> >> > >> > life 
>> >> > >> >> > will
>> >> > >> >> >> not  be entered because the limit is not reached then 
>> > you 
>> >> can 
>> >> > >> > tell 
>> >> > >> >> > the
>> >> > >> >> >> backtester to  enter at the open and exit at the open 
>> > and 
>> >> do 
>> >> > > not 
>> >> > >> >> > allow
>> >> > >> >> >> for a single bar trade  (in the settings window).   
>> > There 
>> >> > > might 
>> >> > >> > be
>> >> > >> >> >> easier ways to do this (I mean using arrays only) but 
> I 
>> >> have  
>> >> > >> > some
>> >> > >> >> >> example code below. I did not check if the code is 
>> >> entirely 
>> >> > >> > correct 
>> >> > >> >> > but 
>> >> > >> >> >> I'll explain the idea: The Buy array is fed to the 
>> >> > > sellAtLimit 
>> >> > >> >> > procedure
>> >> > >> >> >> and  when it finds a buy it will check if the buy 
> limit 
>> > is 
>> >> > >> > reached 
>> >> > >> >> > for
>> >> > >> >> >> that signal.  If it is not reached (so if Low[ i ] >= 
>> >> buyLimit
>> >> > > [ 
>> >> > >> >> > i ] )
>> >> > >> >> >> then you tell the backtester to  enter and exit at 
> the 
>> >> same 
>> >> > >> > price, 
>> >> > >> >> > same
>> >> > >> >> >> bar. What happens is that the backtester  reserves 
> this 
>> >> money 
>> >> > >> > for 
>> >> > >> >> > this
>> >> > >> >> >> trade and will not use it for another trade. The  
> only 
>> >> thing 
>> >> > >> > that 
>> >> > >> >> > is not
>> >> > >> >> >> realistic is that you will pay commission. But this 
>> > will  
>> >> be 
>> >> > > a 
>> >> > >> > small
>> >> > >> >> >> factor.   rgds, Ed     procedure 
>> >> > >> >> >> sellAtLimit_proc(Buy,BuyPrice,buyLimit,sellLimit) {
>> >> > >> >> >> 
>> >> > >> >> >> global Sell;
>> >> > >> >> >> global SellPrice;
>> >> > >> >> >> global BuyAdjusted;
>> >> > >> >> >> global BuyPriceAdjusted;
>> >> > >> >> >> 
>> >> > >> >> >> 
>> >> > >> >> >> // initialise arrays
>> >> > >> >> >> SellPrice = 0;
>> >> > >> >> >> Sell = 0;
>> >> > >> >> >> BuyAdjusted =  0;
>> >> > >> >> >> BuyPriceAdjusted = 0;
>> >> > >> >> >> 
>> >> > >> >> >> for (i = 1; i  < BarCount; i++) {
>> >> > >> >> >> 
>> >> > >> >> >> 
>> >> > >> >> >>     // case where it is likely to enter a  long 
> position
>> >> > >> >> >>     if (Buy[ i ] == 1  AND Low[ i ] < buyLimit[ i ]) {
>> >> > >> >> >> 
>> >> > >> >> >> 
>> >> > >> >> >>        // buy at limit
>> >> > >> >> >>        BuyAdjusted[ i ]  = 1;
>> >> > >> >> >> 
>> >> > >> >> >>        if  (Open[ i ] < buyLimit[ i ]) {
>> >> > >> >> >> 
>> >> > >> >> >> 
>> >> > >> >> >>           BuyPriceAdjusted[ i ] = Open[ i ];
>> >> > >> >> >> 
>> >> > >> >> >>        } else {
>> >> > >> >> >> 
>> >> > >> >> >>           BuyPriceAdjusted[ i ] =  buyLimit[ i ];
>> >> > >> >> >> 
>> >> > >> >> >>        }
>> >> > >> >> >> 
>> >> > >> >> >> 
>> >> > >> >> >>        // find a sell position + sellprice
>> >> > >> >> >>        for (j = i; j < BarCount; j++) {
>> >> > >> >> >> 
>> >> > >> >> >>           if (O[ j ] > sellLimit[ j ]) {
>> >> > >> >> >> 
>> >> > >> >> >>              Sell[ j ] = 1;
>> >> > >> >> >>              SellPrice[ j ] = O[ j ];
>> >> > >> >> >>              i = j;
>> >> > >> >> >>              break;
>> >> > >> >> >> 
>> >> > >> >> >>           } else if (O[ j ] < sellLimit[ j ]  AND H[ 
> j ] 
>> >> 
>> >> > >> > sellLimit
>> >> > >> >> > [ j
>> >> > >> >> >> ]) {
>> >> > >> >> >> 
>> >> > >> >> >>              Sell[ j ] = 1;
>> >> > >> >> >>              SellPrice[ j ] = sellLimit[ j  ];
>> >> > >> >> >>              i = j;
>> >> > >> >> >>              break;
>> >> > >> >> >> 
>> >> > >> >> >>           } else  if (j ==  BarCount -  1) {
>> >> > >> >> >> 
>> >> > >> >> >>              i = BarCount;
>> >> > >> >> >> 
>> >> > >> >> >>           }
>> >> > >> >> >> 
>> >> > >> >> >> 
>> >> > >> >> >> 
>> >> > >> >> >> 
>> >> > >> >> >> 
>> >> > >> >> >>        }
>> >> > >> >> >> 
>> >> > >> >> >>     } else if  (Buy[ i ] ==  1 AND Low[ i ] >= 
> buyLimit[ 
>> >> i ]) 
>> >> > > {
>> >> > >> >> >> 
>> >> > >> >> >>        // enter and exit at the same price and  time 
>> >> ("VOID" 
>> >> > >> > trade)
>> >> > >> >> >>        BuyAdjusted[ i ] = 1;
>> >> > >> >> >>        BuyPriceAdjusted[ i ] = Open[ i ];
>> >> > >> >> >> 
>> >> > >> >> >>        Sell[ i ] = 1;
>> >> > >> >> >>        SellPrice[ i ] = Open[ i ];
>> >> > >> >> >> 
>> >> > >> >> >> 
>> >> > >> >> >>     }
>> >> > >> >> >> 
>> >> > >> >> >> }
>> >> > >> >> >> 
>> >> > >> >> >> 
>> >> > >> >> >> } // end  procedure
>> >> > >> >> >> 
>> >> > >> >> >> 
>> >> > >> >> >> --- In amibroker@xxxxxxxxxxxxxxx, "sfclimbers" 
>> >> <sfclimbers@> 
>> >> > >> > wrote:
>> >> > >> >> >> >
>> >> > >> >> >> > Thanks for your reply. I will look into your 
>> > suggestion, 
>> >> > > but I 
>> >> > >> >> > don't
>> >> > >> >> >> > think that that is the issue that I am up against. 
> I 
>> >> have 
>> >> > >> > actual
>> >> > >> >> >> > trade data from months of live trading. I am now 
>> > trying 
>> >> to 
>> >> > >> >> > backtest
>> >> > >> >> >> > the strategy used, and match the results to the 
> actual 
>> >> data.
>> >> > >> >> >> >
>> >> > >> >> >> > My script, as written, is correctly entering and 
>> > exiting 
>> >> > > with 
>> >> > >> > the
>> >> > >> >> >> > correct number of shares and correct price points 
> on 
>> > all 
>> >> > > the 
>> >> > >> >> > correct
>> >> > >> >> >> > days for all the trades that actually took place.
>> >> > >> >> >> >
>> >> > >> >> >> > The problem is that if I receive 20 "go long" 
> signals 
>> > on 
>> >> > > Monday
>> >> > >> >> >> > night, but only have enough money to afford 8 more 
>> >> > > positions, 
>> >> > >> >> > then in
>> >> > >> >> >> > real life I only place limit orders for the *top* 8 
> of 
>> >> the 
>> >> > > 20
>> >> > >> >> >> > candidates, not all 20.
>> >> > >> >> >> >
>> >> > >> >> >> > This means that in reality, if none of the top 8 
> dip 
>> > to 
>> >> my 
>> >> > >> > limit
>> >> > >> >> >> > order, then I will not get any fills on Tuesday, 
> even 
>> >> > > though I 
>> >> > >> >> > still
>> >> > >> >> >> > have not filled my slots, and even though some of 
> the 
>> >> lesser
>> >> > >> >> >> > candidates would have resulted in a fill had I 
> place 
>> > an 
>> >> > > order 
>> >> > >> > for
>> >> > >> >> >> > them.
>> >> > >> >> >> >
>> >> > >> >> >> > However, the script is considering *all* 20 
>> > candidates, 
>> >> and 
>> >> > >> > fills 
>> >> > >> >> > up
>> >> > >> >> >> > to 8 that dip enough to trigger a limit order. In 
>> > other 
>> >> > > words, 
>> >> > >> > the
>> >> > >> >> >> > script assumes that there are limit orders on all 
>> >> > > candidates 
>> >> > >> >> > instead
>> >> > >> >> >> > of only the top 8.
>> >> > >> >> >> >
>> >> > >> >> >> > Using position score and position sizing is not 
>> > enough, 
>> >> > > since 
>> >> > >> >> > these
>> >> > >> >> >> > assume that the universe of candidates fitting the 
>> >> criteria 
>> >> > > is 
>> >> > >> >> > always
>> >> > >> >> >> > available for prioritizing and filling available 
>> > slots. 
>> >> > > But, in
>> >> > >> >> >> > reality, only a subset are being bid on.
>> >> > >> >> >> >
>> >> > >> >> >> > As an example, if I'm currently holding:
>> >> > >> >> >> > AAA, BBB
>> >> > >> >> >> >
>> >> > >> >> >> > And I then get signals for (in sorted order):
>> >> > >> >> >> > CCC, DDD, EEE, FFF, GGG, HHH, III, JJJ, KKK, 
> LLL, ... 
>> > TTT
>> >> > >> >> >> >
>> >> > >> >> >> > I will only place limit orders for the top 8:
>> >> > >> >> >> > CCC, DDD, EEE, FFF, GGG, HHH, III, JJJ
>> >> > >> >> >> >
>> >> > >> >> >> > If none of the top 8 above reach my limit, but say 
> 8 
>> >> lesser 
>> >> > >> > ones 
>> >> > >> >> > do
>> >> > >> >> >> > (that I did not bid on), then in real life I will 
> get 
>> > no 
>> >> > > fills 
>> >> > >> > for
>> >> > >> >> >> > the day. However, my script is saying that I picked 
> up 
>> >> the 
>> >> > > 8 
>> >> > >> >> > lesser
>> >> > >> >> >> > fills since I had 8 slots open and these 8 met the 
>> > limit 
>> >> > > price.
>> >> > >> >> >> >
>> >> > >> >> >> > How can I structure my code to recognize that 20 
> entry 
>> >> > > setups 
>> >> > >> > were
>> >> > >> >> >> > found, but only 8 of them were acted upon, none of 
>> > which 
>> >> > >> > actually
>> >> > >> >> >> > worked out due to not meeting the limit price?
>> >> > >> >> >> >
>> >> > >> >> >> > I can't seem to use the custom backtester to sweep 
>> >> through 
>> >> > > the 
>> >> > >> >> > orders
>> >> > >> >> >> > and null out the false buys that would not have 
> taken 
>> >> > > place, 
>> >> > >> >> > since I
>> >> > >> >> >> > don't have access to the scores of the candidates 
> that 
>> >> > > didn't 
>> >> > >> > get
>> >> > >> >> >> > filled.
>> >> > >> >> >> >
>> >> > >> >> >> > Yet, similarly, I can't seem to prevent triggering 
> the 
>> >> buys 
>> >> > > in 
>> >> > >> > the
>> >> > >> >> >> > first place, since I don't have access to the 
> scores 
>> > of 
>> >> the 
>> >> > >> > other
>> >> > >> >> >> > candidates at that time either.
>> >> > >> >> >> >
>> >> > >> >> >> > When there are fewer signals than slots to fill, 
>> >> everything 
>> >> > > is
>> >> > >> >> >> > great :) But this strategy often results in more 
>> > signals 
>> >> > > than 
>> >> > >> >> > there
>> >> > >> >> >> > is money to bid with :(
>> >> > >> >> >> >
>> >> > >> >> >> > Thanks.
>> >> > >> >> >> >
>> >> > >> >> >> >
>> >> > >> >> >> > --- In amibroker@xxxxxxxxxxxxxxx, "Edward Pottasch" 
>> >> > > empottasch@
>> >> > >> >> >> > wrote:
>> >> > >> >> >> > >
>> >> > >> >> >> > > hi,
>> >> > >> >> >> > >
>> >> > >> >> >> > > the way you set it up it shoudl not be possible. 
>> >> However, 
>> >> > >> > what 
>> >> > >> >> > can
>> >> > >> >> >> > happen is that the backtester finds exits for the 
> next 
>> >> day 
>> >> > > and
>> >> > >> >> >> > immediatelly fills them with new positions. So you 
>> > need 
>> >> to 
>> >> > >> > make 
>> >> > >> >> > sure
>> >> > >> >> >> > that you first exit your positions and tell the 
>> >> backtester 
>> >> > > to 
>> >> > >> >> > enter
>> >> > >> >> >> > only on the next bar. This is usually the problem.  
>> >> There 
>> >> > > are 
>> >> > >> >> > several
>> >> > >> >> >> > ways to achieve this. Maybe you will get a more 
>> >> > > satisfactory 
>> >> > >> >> > result
>> >> > >> >> >> > when you set settradedelays(1,1,1,1).
>> >> > >> >> >> > >
>> >> > >> >> >> > > I use setttradedelays(0,0,0,0) but I make sure 
> that 
>> >> the 
>> >> > >> > trade is
>> >> > >> >> >> > entered 1 bar after the signal (same with the 
> exits),
>> >> > >> >> >> > >
>> >> > >> >> >> > > Ed
>> >> > >> >> >> > >
>> >> > >> >> >> > >
>> >> > >> >> >> > >
>> >> > >> >> >> > >
>> >> > >> >> >> > >   ----- Original Message -----
>> >> > >> >> >> > >   From: Michael White
>> >> > >> >> >> > >   To: amibroker@xxxxxxxxxxxxxxx
>> >> > >> >> >> > >   Sent: Friday, August 24, 2007 11:37 AM
>> >> > >> >> >> > >   Subject: [amibroker] How do I backtest placing 
> a 
>> >> > > restricted
>> >> > >> >> >> > number of limit orders each night?
>> >> > >> >> >> > >
>> >> > >> >> >> > >
>> >> > >> >> >> > >   Can anyone help me model the following scenario?
>> >> > >> >> >> > >
>> >> > >> >> >> > >   - Assume a portfolio is allowed to consist of 
> some 
>> >> > > fixed 
>> >> > >> >> > number
>> >> > >> >> >> > >   of "slots" with equity equally divided among 
> them 
>> >> (e.g. 
>> >> > > 10 
>> >> > >> >> > slots
>> >> > >> >> >> > at
>> >> > >> >> >> > >   10% of equity).
>> >> > >> >> >> > >   - Check for setup criteria at close of each day.
>> >> > >> >> >> > >   - Place next day limit buy orders for as many 
>> >> unfilled 
>> >> > >> > slots 
>> >> > >> >> > as
>> >> > >> >> >> > are
>> >> > >> >> >> > >   currently available (e.g. if already have 2 
> fills 
>> >> after 
>> >> > >> > day 1,
>> >> > >> >> >> > then
>> >> > >> >> >> > >   there are only 10 - 2 = 8 slots remaining for 
> day 
>> > 2, 
>> >> > > etc.).
>> >> > >> >> >> > >   - Buy orders are prioritized by a calculated 
> value.
>> >> > >> >> >> > >
>> >> > >> >> >> > >   My problem is that if I receive a setup for 
> more 
>> >> > > symbols 
>> >> > >> > than 
>> >> > >> >> > I
>> >> > >> >> >> > have
>> >> > >> >> >> > >   available slots (e.g. receive 20 setups but 
> only 
>> >> have 8 
>> >> > >> >> > available
>> >> > >> >> >> > >   slots), my script will try to fill all 8 slots 
>> > from 
>> >> the 
>> >> > > 20
>> >> > >> >> >> > >   candidates, and the portfolio manager will 
>> > correctly 
>> >> > >> > prevent 
>> >> > >> >> > me
>> >> > >> >> >> > from
>> >> > >> >> >> > >   having more positions than allowed (e.g. no 
> more 
>> >> than 
>> >> > > 10).
>> >> > >> >> >> > >
>> >> > >> >> >> > >   However, in reality, I will only have placed as 
>> > many 
>> >> > > limit 
>> >> > >> >> > orders
>> >> > >> >> >> > as
>> >> > >> >> >> > >   I have available slots (e.g. 8 limit orders 
> when 8 
>> >> > >> > available
>> >> > >> >> >> > slots,
>> >> > >> >> >> > >   not limit orders for all 20 candidates, since I 
>> > only 
>> >> > > have 
>> >> > >> >> > funds
>> >> > >> >> >> > to
>> >> > >> >> >> > >   cover placing 8 orders).
>> >> > >> >> >> > >
>> >> > >> >> >> > >   What is happening is that my script is filling 
>> >> orders 
>> >> > > that 
>> >> > >> > I
>> >> > >> >> >> > would
>> >> > >> >> >> > >   not have placed! I need a way to indicate that 
>> >> despite 
>> >> > > 20 
>> >> > >> >> > setups,
>> >> > >> >> >> > >   only 8 limit orders were placed.
>> >> > >> >> >> > >
>> >> > >> >> >> > >   Following is some script snippets.
>> >> > >> >> >> > >
>> >> > >> >> >> > >   /*
>> >> > >> >> >> > >   * Assume an initial purse and brokerage fees 
>> >> > > ($0.01/share)
>> >> > >> >> >> > >   */
>> >> > >> >> >> > >   SetOption("InitialEquity", 50000);
>> >> > >> >> >> > >   SetOption("CommissionMode", 3);
>> >> > >> >> >> > >   SetOption("CommissionAmount", 0.01);
>> >> > >> >> >> > >
>> >> > >> >> >> > >   /*
>> >> > >> >> >> > >   * Carry fixed number of positions, dividing 
> 100% 
>> > of 
>> >> > > Equity 
>> >> > >> >> > between
>> >> > >> >> >> > >   * them (based on previous bar's closing).
>> >> > >> >> >> > >   */
>> >> > >> >> >> > >   PositionSize = -100/10; // Each position is 10% 
> of 
>> >> > > equity
>> >> > >> >> >> > >
>> >> > >> >> >> > >   SetOption("MaxOpenPositions", 10); // No more 
> than 
>> >> 10 
>> >> > >> >> > positions
>> >> > >> >> >> > >   SetOption("UsePrevBarEquityForPosSizing", True);
>> >> > >> >> >> > >
>> >> > >> >> >> > >   /*
>> >> > >> >> >> > >   * We recognize the sale signal at the close of 
> a 
>> > bar 
>> >> > > and 
>> >> > >> >> > execute
>> >> > >> >> >> > the
>> >> > >> >> >> > >   * sale at the open of the next one, delay sale 
> by 
>> > 1 
>> >> day.
>> >> > >> >> >> > >   */
>> >> > >> >> >> > >   SetTradeDelays(0, 1, 0, 0);
>> >> > >> >> >> > >
>> >> > >> >> >> > >   /*
>> >> > >> >> >> > >   * Trigger a Buy signal when previous bar meets 
> the 
>> >> setup
>> >> > >> >> >> > >   * requirements AND this bar's Low has dropped 
> to 
>> >> less 
>> >> > > than 
>> >> > >> > a 
>> >> > >> >> > fixed
>> >> > >> >> >> > >   * percentage below the previous bar's close. 
> This 
>> >> > > emulates 
>> >> > >> >> > having
>> >> > >> >> >> > >   * placed a limit order the night before after 
>> > having 
>> >> > > seen 
>> >> > >> > the
>> >> > >> >> >> > signal
>> >> > >> >> >> > >   * on that day's close.
>> >> > >> >> >> > >   */
>> >> > >> >> >> > >   setup = ... // Some position entry logic.
>> >> > >> >> >> > >   PositionScore = ... // Some prioritization 
> logic.
>> >> > >> >> >> > >
>> >> > >> >> >> > >   BuyPrice = Ref(Close, -1) * 0.95;
>> >> > >> >> >> > >   Buy = Ref(setup, -1) AND Low <= BuyPrice; // 
>> > Problem 
>> >> > >> > here!!!
>> >> > >> >> >> > >
>> >> > >> >> >> > >   Sell = ... // Some sell logic.
>> >> > >> >> >> > >
>> >> > >> >> >> > >   As indicated in my earlier comments. The 
> problem 
>> > is 
>> >> > > that in
>> >> > >> >> >> > reality I
>> >> > >> >> >> > >   will not actually have placed orders for all 
>> >> > > candidates, 
>> >> > >> > but
>> >> > >> >> >> > rather
>> >> > >> >> >> > >   only for as many as there are available slots 
>> > (e.g. 
>> >> 8). 
>> >> > >> >> > However,
>> >> > >> >> >> > the
>> >> > >> >> >> > >   script will attempt to fill the available slots 
>> >> based 
>> >> > > on 
>> >> > >> > all
>> >> > >> >> >> > >   candidates (e.g. 20).
>> >> > >> >> >> > >
>> >> > >> >> >> > >   How can I restrict the Buy assignment to only 
>> > apply 
>> >> to 
>> >> > > the 
>> >> > >> >> > top X
>> >> > >> >> >> > of Y
>> >> > >> >> >> > >   candidates based on priority (e.g. top 8 of 20 
> in 
>> >> > > example 
>> >> > >> >> > above).
>> >> > >> >> >> > >
>> >> > >> >> >> > >   Thanks in advance.
>> >> > >> >> >> > >
>> >> > >> >> >> >
>> >> > >> >> >>
>> >> > >> >> > 
>> >> > >> >> > 
>> >> > >> >> > 
>> >> > >> >> > 
>> >> > >> >> > Please note that this group is for discussion between 
>> > users 
>> >> > > only.
>> >> > >> >> > 
>> >> > >> >> > To get support from AmiBroker please send an e-mail 
>> >> directly 
>> >> > > to 
>> >> > >> >> > SUPPORT {at} amibroker.com
>> >> > >> >> > 
>> >> > >> >> > For NEW RELEASE ANNOUNCEMENTS and other news always 
> check 
>> >> > > DEVLOG:
>> >> > >> >> > http://www.amibroker.com/devlog/
>> >> > >> >> > 
>> >> > >> >> > For other support material please check also:
>> >> > >> >> > http://www.amibroker.com/support.html
>> >> > >> >> > 
>> >> > >> >> > Yahoo! Groups Links
>> >> > >> >> > 
>> >> > >> >> > 
>> >> > >> >> > 
>> >> > >> >> > 
>> >> > >> >> >
>> >> > >> >>
>> >> > >> > 
>> >> > >> > 
>> >> > >> > 
>> >> > >> > 
>> >> > >> > Please note that this group is for discussion between 
> users 
>> >> only.
>> >> > >> > 
>> >> > >> > To get support from AmiBroker please send an e-mail 
> directly 
>> >> to 
>> >> > >> > SUPPORT {at} amibroker.com
>> >> > >> > 
>> >> > >> > For NEW RELEASE ANNOUNCEMENTS and other news always check 
>> >> DEVLOG:
>> >> > >> > http://www.amibroker.com/devlog/
>> >> > >> > 
>> >> > >> > For other support material please check also:
>> >> > >> > http://www.amibroker.com/support.html
>> >> > >> > 
>> >> > >> > Yahoo! Groups Links
>> >> > >> > 
>> >> > >> > 
>> >> > >> > 
>> >> > >> > 
>> >> > >> >
>> >> > >>
>> >> > > 
>> >> > > 
>> >> > > 
>> >> > > 
>> >> > > Please note that this group is for discussion between users 
>> > only.
>> >> > > 
>> >> > > To get support from AmiBroker please send an e-mail directly 
> to 
>> >> > > SUPPORT {at} amibroker.com
>> >> > > 
>> >> > > For NEW RELEASE ANNOUNCEMENTS and other news always check 
>> > DEVLOG:
>> >> > > http://www.amibroker.com/devlog/
>> >> > > 
>> >> > > For other support material please check also:
>> >> > > http://www.amibroker.com/support.html
>> >> > > 
>> >> > > Yahoo! Groups Links
>> >> > > 
>> >> > > 
>> >> > > 
>> >> > > 
>> >> > >
>> >> >
>> >>
>> > 
>> > 
>> > 
>> > 
>> > Please note that this group is for discussion between users only.
>> > 
>> > To get support from AmiBroker please send an e-mail directly to 
>> > SUPPORT {at} amibroker.com
>> > 
>> > For NEW RELEASE ANNOUNCEMENTS and other news always check DEVLOG:
>> > http://www.amibroker.com/devlog/
>> > 
>> > For other support material please check also:
>> > http://www.amibroker.com/support.html
>> > 
>> > Yahoo! Groups Links
>> > 
>> > 
>> > 
>> > 
>> >
>>
> 
> 
> 
> 
> Please note that this group is for discussion between users only.
> 
> To get support from AmiBroker please send an e-mail directly to 
> SUPPORT {at} amibroker.com
> 
> For NEW RELEASE ANNOUNCEMENTS and other news always check DEVLOG:
> http://www.amibroker.com/devlog/
> 
> For other support material please check also:
> http://www.amibroker.com/support.html
> 
> Yahoo! Groups Links
> 
> 
> 
> 
>


Please note that this group is for discussion between users only.

To get support from AmiBroker please send an e-mail directly to 
SUPPORT {at} amibroker.com

For NEW RELEASE ANNOUNCEMENTS and other news always check DEVLOG:
http://www.amibroker.com/devlog/

For other support material please check also:
http://www.amibroker.com/support.html
 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/amibroker/

<*> Your email settings:
    Individual Email | Traditional

<*> To change settings online go to:
    http://groups.yahoo.com/group/amibroker/join
    (Yahoo! ID required)

<*> To change settings via email:
    mailto:amibroker-digest@xxxxxxxxxxxxxxx 
    mailto:amibroker-fullfeatured@xxxxxxxxxxxxxxx

<*> To unsubscribe from this group, send an email to:
    amibroker-unsubscribe@xxxxxxxxxxxxxxx

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/