I don't know if this helps. But Ed helped with the same issue about
a
month ago. The workaround trick was to realize that you can "fool"
the
portfolio manager by creating null trades. Trades that enter and
exit on
the same bar at the same price (i use the bar open as the
price).
This has the effect of creating a limit order that doesn't
get filled
but still occupies a slot. The code snippet below looks at the
previous day's bar to see if there was an entry signal. If yes, it
looks at the current bar to see if the low is less than the entry
price based on the day's before's bar. If this order triggers, that
is
to say the Low is less than the limit entry, the stock is bought.
If the
entry is not going to be made, ie. the low price never passes
through the
entry price, then I enter both a buy and a sell at the
open price -
creating a trade that results in $0.
The postprocessor will correctly
allocate the trades based on
position score and current equity. There are
two problems with this
method. First all trades are reported in the trade
list, you get a
lot of null trades. Second is if you model comissions,
each null
trade will requrie a round-trip commission. I personally never
model
in commisions. I export my tradelist to Excel and remove the null
trades for further analysis to get around the first problem.
Hope
this
helps
RLT
----------------------------------------
Vers
= 1.000;
Qty = 10;
// #Open Postions Allowed
// Sell 10 days after
crossing MA
// Optimazation Variables
MATgt = Optimize("MATgt", 2,
2, 7, 1 ); // target moving average
crossover for sale
SaleDelay =
Optimize("SDly", 0, 0, 5, 1);
PBCct = 2.00 ; // 2%
pullback
SetOption("MaxOpenPositions", PosQty
);
PositionSize = -100/PosQty; //
invest 100% of portfolio equity
divided by max. position count
Setup = C > MA(C, 10 );
PriceTrigger = Ref(C, -1) * (1 - PBPct /100);
FCross = C >
MA(C,MaTgt);
PositionScore = Ref(HV100, -1);
PositionCount =
0;
ScaleIn = 1;
Sell = 0;
Buy = 0;
BarnumberBuy =
0;
//
// Trading Loop
//
for (i = 2; i < BarCount; i++) {
PositionSize = -100/PosQty;
PositionCount[i] =
PositionCount[i-1];
if (Fcross[i-1 - SaleDelay] AND
(PositionCount[i] >
0) // <- sell any open
positions
{
Sell[i] = 1;
SellPrice[i] =
O[i];
PositionCount[i] = 0;
}
if (Setup[i-1] AND
(PositionCount[i-1] == 1) AND
(ScaleIn == 1)) // <-Scale in if
scalein enabled
{
PositionCount[i] = 2;
Buy[i] =
sigScaleIn;
BuyPrice[i] = O[i];
BarNumberBuy = i;
}
else if
(Setup[i-1] AND (PositionCount[i-1] == 0) AND (L[i] <=
PriceTrigger[i])) // <-Take a new position
{ // take a
newposition
PositionCount[i] = 1;
Buy[i] = 1;
BuyPrice[i] =
PriceTrigger[i];
BarNumberBuy = i;
}
else if (Setup[i-1] AND
(L[i] > PriceTrigger[i])
AND PositionCount[i-1] == 0 ) //
<- create a null position
{
Buy[i] = 1;
BuyPrice[i] =
O[i];
Sell[i] = 1;
SellPrice[i] = O[i];
PositionSize =
0;
};
--- In amibroker@xxxxxxxxxps.com,
"vlanschot" <vlanschot@x..> wrote:
>
> Hi Ton,
>
> Perhaps looking at the rotational trading version can help to
clarify
> things (I hope).
>
> In line with your
argument, new signals have no effect UNLESS some
> condition is met
which rebalances the portfolio. This is easiest
> perceived in
rotational mode, since it forces the portfolio
> to "rebalance" at each
bar. I hope we can agree that one has to
have
> some conviction as
to the explanatory power for excess returns of
> the "factors" (or
think "indicators") which are used to define the
> condition. In
other words, any score on a factor (momentum,
> valuation, etc.)
implies its relative expected return, i.e. a
higher
> score is
preferable. If we agree on that then, based on your
> condition, unless
an existing holding meets this condition (i.e.
has
> the minimum
score) it is replaced by another security (assuming at
> least one
meets this condition). In case of the condition being
met,
> any
new signals are legitimately "superfluous" in that they are not
>
better signals. Otherwise our previous agreement falls apart. The
>
only way, in my view, in which new (or rather confirming) signals
are
> put into practise in the portfolio is by adding/deducting to the
> weights of existing holdings (particularly if you're judged against
a
> benchmark) which is where scalein/out comes in.
>
> Now, first, any rotational system can (often more flexibly) be
> implemented via ordinary BSSC-rules. Second, I do agree that there
> are limitations to backtesters, even AB's CBT. The main one
>
is "custom cash management": the inability to allocate cash from
>
individual sells (which should be completed first) to individual
>
buys. An extension of this is the inability to use cash from shorts
>
to enter additional longs, i.e. create 130/30 portfolios (although
TJ
> has promised to look into this functionality).
>
>
May be too much OT, but hope it helps.
>
> PS
> --- In amibroker@xxxxxxxxxps.com,
"Ton Sieverding"
> <ton.sieverding@> wrote:
>
>
> > Thanks Mike. I know all this. Please read my answers to Ed
and
you
> will find the real problem I have with the Backtester and
whatever
> Backtester. Because it has nothing to do with the AB
Backtester.
It's
> just the portfolio constraint that every
investor in the real world
> has creating mentioned problem. I just
don't know how to solve
it ...
> >
> > Regards,
Ton.
> >
> > ----- Original Message -----
> >
From: sfclimbers
> > To: amibroker@xxxxxxxxxps.com
> > Sent: Tuesday, August 28, 2007 9:19 PM
> > Subject:
[amibroker] Re: How do I backtest placing a restricted
> number of
limit orders each night?
> >
> >
> > Ton,
>
>
> > Once your portfolio is full, yes, PositionScore will have
no
> effect
> > until a slot becomes available after a
Sell.
> >
> > However, a PositionScore is only good for the
life of the bar
> (single
> > day when using EOD data). So if
it can not be acted upon *in
that
> > bar*, then it is worthless
from that point on. The markets will
> have
> > changed by
the next bar and the score will no longer apply.
> >
> >
Once one or more slots become open (after a Sell), then the
> *current*
> > PositionScore(s) will be considered, and the best will be
used
to
> > fill the open slot(s). So no, the process is not
random. The
> > *current* PositionScore is used to fill any open
slots of a
> > portfolio. "Expired" PositionScore(s) are of no
use.
> >
> > If you have a restriction in your strategy
that prevent
entering
> > multiple positions for a single symbol
(i.e. prvents "scale-
in",
> > which is the default case), then
entering a position for that
> symbol
> > will be rejected,
even if it has the highest PositionScore. But
> that
> > is
based on your strategy, not luck.
> >
> > The next highest
will be evaluated until one is found that can
be
> > traded in
accordance with the rules of your strategy. The
process
> is
> > predictable.
> >
> > Hope that helps,
>
>
> > Mike
> >
> > --- In amibroker@xxxxxxxxxps.com,
"Ton Sieverding"
> > <ton.sieverding@> wrote:
>
> >
> > > As far as I understand Ed and assuming EOD
trading,
> PositionScore
> > is selecting the best signals
coming from the same day. So when
> at
> > Day1 there are 10
different signals where only one is needed
then
> >
PositionScore is selecting the 'best' signal. But what if the
> next
> > day all stocks in portfolio are filled and the system generates
> > another 10 signals? They are lost ... until the system gives a
> SELL.
> > Therefore the next BUY is based upon the next
SELL. Put the 500
> > stocks of the SP500 in a WatchList, take
whatever AFL rules for
> the
> > BUY and the SELL and a
portfolio with say max. 10 stocks. Do a
> > Backtest and what you
see is that only a small part of the
> signals
> > were used
to fill the portfolio. Simply because you have this
> > portfolio
constraint. If all signals would give you the same
> > Winner/Looser
characteristics than there should be no problem.
> But
> >
that's not true. Therefore the portfolio filling proces for me
> has a
> > random character and the result is based upon luck ... Unless I
> am
> > missing something ... And that's my question.
> > >
> > > Regards, Ton.
> > >
>
> >
> > > ----- Original Message -----
> > >
From: ed2000nl
> > > To: amibroker@xxxxxxxxxps.com
> > > Sent: Monday, August 27, 2007 12:58 PM
> > >
Subject: [amibroker] Re: How do I backtest placing a
restricted
>
> number of limit orders each night?
> > >
> > >
> > > hi Ton,
> > >
> > > I'm not sure
if I understand what you mean. There are often
more
> > >
signals then you can use but the backtester is instructed to
> pick
> > the
> > > best signals using PositionScore. I can
exactly perform my
> > backtest in
> > > the real world,
excluding the shorts I am not allowed to
enter
> by
> >
my
> > > broker. The signals the backtester chooses are not pure
luck
but
> > > chosen using positionscore. But I guess I do
not understand
> your
> > question,
> > >
> > > rgds, Ed
> > >
> > > --- In amibroker@xxxxxxxxxps.com,
"Ton Sieverding"
> > > <ton.sieverding@> wrote:
>
> > >
> > > > Morning Ed,
> > > >
> > > > My problem when using the Backtester and in general a
> Backtester
> > > based upon portfolio result is the fact
that in the real
world
> an
> > > investor will have a
portfolio with
> > > > let's day 20 stocks. Therefore when the
portfolio has been
> > filled,
> > > all other BUY
signals
> > > > will be lost until you've a SELL signal. For
this reason
when
> > doing
> > > a Backtest
>
> > > I always do an Explore analysis of all signals. In general
> what
> > I
> > > get is something like
>
> > > 200 Transactions from the Backtester and 1.000 Transactions
> > from the
> > > Explore analysis.
> > >
> What makes things worse, I often get a RAR from the
backtest
>
of
> > > let's say 25% with
> > > > 75% of the
signals being winners. When looking to the
Explore
> > >
analysis of all the
> > > > signals I only get something like
35% of winners. Therefore
> the
> > > result coming
from
> > > > the Backtester must be pure luck. The backtester
'randomly'
> > chooses
> > > the signals to
> >
> > fill the portfolio. I have no idea how to solve this
>
problem ...
> > > >
> > > > Regards,
Ton.
> > > >
> > > >
> > > >
> > > > ----- Original Message -----
> > > >
From: Edward Pottasch
> > > > To: amibroker@xxxxxxxxxps.com
> > > > Sent: Sunday, August 26, 2007 8:45 PM
> >
> > Subject: Re: [amibroker] How do I backtest placing a
>
restricted
> > > number of limit orders each night?
> >
> >
> > > >
> > > >
> > >
> 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@xxxxxxxxxps.com
> > > > 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.
> > > >
> >
>
>
>
>