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

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



PureBytes Links

Trading Reference Links

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

<*> 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/