[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

Ed,

Very creative! I will try integrating this into my own code and see 
if I can get it to behave as expected. My script allows for scale in, 
so I've still got a bit more work ahead of me.

For those reading along, Ed's original reply to a similar request, 
including a complete script showing the usage of the procedure below, 
can be found in message ID #113384.

Thanks again,

Mike

--- In amibroker@xxxxxxxxxxxxxxx, "ed2000nl" <empottasch@xxx> 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

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