PureBytes Links
Trading Reference Links
|
Anybody? . . .
Thx,
PS
--- In amibroker@xxxxxxxxxxxxxxx, "vlanschot" <vlanschot@xxx> wrote:
>
> Yes, still struggling with this one, so I would appreciate any
> guidance from the CBT-experts, like Graham, GP, and Ed (and TJ, of
> course). I've included a stripped-down version of my CBT-code (see
> below) which you may use to verify my strange observations.
>
> // CODE SECTION
>
> // USE on WEEKLY DATA !!!
>
> FullYr=52;
> AnnPer=52;
> QtrPer=13;
> MonthPer=4;
> WeekPer=1;
> DayPer=1/5;
>
> ShortTrades = ParamToggle("Short Trades?","No|Yes",1);
>
> MaxOpenPos = 50; // maximum total positions
> //MaxShort = Param("ChoiceMaxShort",round((MaxOpenPos / 100) *
> 50),0,MaxOpenPos);
>
> SetOption("MaxOpenPositions",MaxOpenPos);
>
> Startkapitaal = 1000000;
>
> SetOption("InitialEquity", Startkapitaal);
>
> if (ShortTrades==1)
> {
> MaxLong = round((MaxOpenPos / 100) * 50);
> MaxShort = round((MaxOpenPos / 100) * 50);
> TypePos = "_LS";
> LongPS = ShortPS = -100/(MaxLong+MaxShort);
> }
> else if (ShortTrades==0)
> {
> MaxLong = MaxOpenPos;
> MaxShort = 0;
> TypePos = "_LO";
> LongPS = -100/(MaxLong+MaxShort);
> ShortPS = 0;
> }
>
> NaamBT = "~Trial_LS_";
>
> BM = "MSWRLD$";
>
> BMI=Foreign(BM,"C");
>
> MA1 = Param("MA1",AnnPer,6*MonthPer,AnnPer,MonthPer);
> MA2 = Param("MA2",MonthPer,5*MonthPer,5*MonthPer,MonthPer);
>
> Mom = ROC(C,MA1)-ROC(C,MA2);
> BMMom= ROC(BMI,MA1)-ROC(BMI,MA2);
> RelMom = Mom-BMMom;
>
> Buy=RelMom>=0; Sell=RelMom<0;
> PositionScore=RelMom;
>
> if (ShortTrades==1)
> {
> Short=Sell; Cover=Buy;
> }
> else Short=Cover=0;
>
> PositionSize= IIf(Buy,LongPS,IIf(Short,ShortPS,0));
>
> if (Interval()==inWeekly OR Interval() == inMonthly)
> BuyPrice=SellPrice=ShortPrice=CoverPrice=Open;
> else BuyPrice=SellPrice=ShortPrice=CoverPrice=Close;
>
> TextOutput = ParamToggle("Raw Text Output?", "No|Yes");
>
> UseCBT = ParamToggle("Use CBT?", "No|Yes",1);
>
> FBT=LastValue(ValueWhen(Status("firstbarintest")==1,BarIndex()));
> LBT=LastValue(ValueWhen(Status("lastbarintest")==1,BarIndex()));
>
> SetOption("UseCustomBacktestProc", UseCBT );
>
> if( Status("action") == actionPortfolio )
> {
> bo = GetBacktesterObject();
>
> bo.PreProcess(); // Initialize backtester
>
> for(bar=0; bar<BarCount; bar++)
> {
> NrOpenPos = 0;
> NrOpenLongs = 0;
> NrOpenShorts = 0;
> NrNewLongs = 0;
> NrNewShorts = 0;
> numExits = 0;
>
> bContinueLong = bContinueShort = True;
>
> // First, list Exit Signals, and execute exit trades
> for ( sig=bo.GetFirstSignal(bar); sig;
> sig=bo.GetNextSignal(bar) )
> {
> if (sig.IsExit() AND sig.Price != -1 )
> {
> // Exit Trade
> GoExit = bo.ExitTrade
> (bar,sig.symbol,sig.Price);
>
> if (GoExit==1) numExits = numExits +
> 1;
> }
> }
>
> if (TextOutput==1)
> {bo.RawTextOutput("Nr Exits = " + numExits );
> bo.UpdateStats(bar,0);}
>
> //Second, establish remaining nr open positions
> for( pos = bo.GetFirstOpenPos(); pos; pos =
> bo.GetNextOpenPos() )
> {
> if (pos.IsLong) {LS =1; NrOpenLongs = NrOpenLongs+1;}
> else if (!pos.IsLong){ LS = -1; NrOpenShorts = NrOpenShorts +
> 1;}
> // All pos are open, so pos.IsOpen not necessary
>
> NrOpenPos = NrOpenPos + 1;
> }
>
> if (TextOutput==1)
> {
> bo.RawTextOutput("Nr Open Longs = " +
> NrOpenLongs);
> bo.RawTextOutput("Nr Open Shorts = " +
> NrOpenShorts);
> bo.RawTextOutput("Nr Open Posits = " +
> NrOpenPos);
> }
>
> if (NrOpenLongs>=MaxLong) bContinueLong = False;
> if (NrOpenShorts>=MaxShort) bContinueShort = False;
>
>
> // update stats
> bo.UpdateStats(bar,0);
>
> Kas=bo.Cash; Eq = bo.Equity;
>
> if (bar>1) NewPosSize = Nz((Kas[bar]/numExits)/Eq[bar]
> *100, 100/MaxOpenPos);
> else NewPosSize = 100/MaxOpenPos ;
>
> LongPS = ShortPS = -NewPosSize;
>
> if (TextOutput==1) bo.RawTextOutput("New PosSize = "
> + -NewPosSize );
>
> // Next, look for conditional Entry Signals
> for ( sig=bo.GetFirstSignal(bar); sig ;
> sig=bo.GetNextSignal(bar))
> {
> if( sig.IsEntry() AND sig.Price != -1 AND
> IsNull( bo.FindOpenPos( sig.Symbol ) ) )
> {
> // Enter Long
> if( sig.IsLong() AND NrNewLongs <=
> (MaxLong-NrOpenLongs) AND bContinueLong)
> {
> GoLong = bo.EnterTrade(bar,
> sig.symbol, True, sig.Price, LongPS );
>
> if( GoLong == 0 )
> bContinueLong = False;//If trade doesn't go through don't do
anymore
> trades
> else
> NrNewLongs = NrNewLongs + 1;
>
> }
> // Enter Short
> else if ( sig.IsLong()==0 AND
> NrNewShorts <= (MaxShort - NrOpenShorts) AND bContinueShort)
> {
> GoShort = bo.EnterTrade(bar,
> sig.symbol, False, sig.Price, ShortPS);
>
> if( GoShort == 0 )
> bContinueShort = False;//If trade doesn't go through don't do
anymore
> trades
> else NrNewShorts =
> NrNewShorts + 1;
> }
> }
> }
>
> if (TextOutput==1)
> {
> bo.RawTextOutput("Nr NewLong = " +
> NrNewLongs);
> bo.RawTextOutput("Nr NewShort = " +
> NrNewShorts );
> bo.RawTextOutput("Cash End = " + Kas[bar] );
> }
>
> bo.ProcessTradeSignals( bar );
> }
>
> bo.PostProcess(1);// Finalize backtester, but (1) means: do
> NOT list trades
> // i.e. use AddCustomMetric (see below) to add custom metrics
to
> BT-report.
>
> SumProfitPerRisk = 0;
> NumTrades = 0;
>
> // ADDED LINE
> dt = DateTime();
>
> AddToComposite( Foreign
("~~~EQUITY","C"), "~~"+NaamBT+TypePos, "C",
> atcFlagDefaults | atcFlagEnableInPortfolio );
> AddToComposite( Foreign
> ("~~~EQUITY","L"), "~~"+NaamBT+TypePos, "L", atcFlagDefaults |
> atcFlagEnableInPortfolio );
>
> CategoryAddSymbol("~~"+NaamBT+TypePos, categoryGroup ,
> 250 );
>
> Eq = Foreign("~~"+NaamBT+TypePos,"C");
>
> WBM = BMI = Foreign(BM, "C");
>
> BMR=ROC(WBM,1)/100;
> PFRet=ROC(Eq,1)/100;
>
> ThisTestLB=LBT-FBT;
> SystPerfFullP=(Eq[LBT]/StartKapitaal-1)*100;
>
> BMPerfFullP=(BMI[LBT]/BMI[FBT]-1)*100;
>
> SystRetsFullP=PFRet;
>
> bo.AddCustomMetric("Other Stats (OTP = over test-period):","" );
> bo.AddCustomMetric("Relative Performance OTP (%)",
> SystperfFullP-BMPerfFullP);
>
> bo.ListTrades();
> }
>
> // END OF CODE
>
> As you can see, the code:
>
> 1) executes (and counts) all exits, in order to release as much
cash
> as possible;
> 2) determines the number of remaining long/short open positions;
> 3) switches the bContinueLong/-Short trigger to FALSE, as soon as
the
> open-long, respectively open-short positions are equal to the
> respective prespecified maximum positions;
> 4) enters in the signal loop, executes long, respectively short
> trades UNTIL (again) it hits the respective maximum positions.
>
> In short, I would like to hold an equal number (default: 25) of
long
> and short positions, and I had hoped that this code would achieve
> this. However, if you run this, it shows, for example:
>
> Nr Exits = 1
> Nr Open Longs = 23
> Nr Open Shorts = 26
> Nr Open Posits = 49
>
> So, although the number of remaining open positions (49) correctly
> reflects the required maximum open positions (50) minus any exits,
it
> also (and strangely) regularly shows that the number of open-longs
or
> open-shorts during the backtest exceed the maximum required
> long/shorts. And this is not caused by a lack of long/short signals.
>
> I don't understand this, although it could simply be a case
of "code-
> blindness" with an easy solution. Again, any help much appreciated.
>
> PS
>
>
> --- In amibroker@xxxxxxxxxxxxxxx, Graham <kavemanperth@> wrote:
> >
> > You need to actually check how many open positions you have after
> the
> > exits and thus how many new trades you need to enter. You can do
> this
> > with openpos loop
> > Then use bo.Cash to determine the position size for the new
entries
> >
> > --
> > Cheers
> > Graham Kav
> > AFL Writing Service
> > http://www.aflwriting.com
> >
> >
> > On 01/02/2008, vlanschot <vlanschot@> wrote:
> > > Thanks Graham,
> > >
> > > A follow-up question if I may.
> > >
> > > Indeed, in my CBT-loops, I first execute the exits, and keep
> track of
> > > the number of exits. Based on this, and after bo.UpdateStats,
I've
> > > added the following:
> > >
> > > (FYI: Cash = bo.Cash Eq = bo.Equity)
> > >
> > > if (bar>1) NewPosSize = Nz((Kas[bar]/numExits)/Eq[bar],
> > > MaxOpenPos/100);
> > > else NewPosSize = MaxOpenPos/100 ;
> > >
> > > LongPS = ShortPS = -NewPosSize*100;
> > >
> > > I then run through my entry signals.
> > >
> > > In other words, I assume the CBT re-calculates the cash amount
> after
> > > exits, which I subsequently divide evenly over the potential new
> > > positions.
> > >
> > > However, for some reason I end up with less than 50 positions
(my
> > > MaxOpenPos) at the end of the backtest. Whereas if I "delete"
the
> > > above code, I do end up with 50 positions, but then with too
much
> > > cash occassionally. Iow, the system generates enough valid
> signals to
> > > fill any exits.
> > >
> > > Any clarification appreciated, although I realize I'm not
giving
> you
> > > much detail.
> > >
> > > PS
> > >
> > > --- In amibroker@xxxxxxxxxxxxxxx, Graham <kavemanperth@> wrote:
> > > >
> > > > In advanced backtest code you exit the trades, update the
> values,
> > > then
> > > > enter signals with amended posSize
> > > >
> > > > --
> > > > Cheers
> > > > Graham Kav
> > > > AFL Writing Service
> > > > http://www.aflwriting.com
> > > >
> > > >
> > > > On 01/02/2008, vlanschot <vlanschot@> wrote:
> > > > > Perhaps somebody has a straightforward way to solve the
> > > following, or
> > > > > point out the error in my interpretation of AFL/CBT:
> > > > >
> > > > > My system keeps a constant number of 50 positions, based on
a
> > > ranking
> > > > > (although I do not use rotational trading.) At the start the
> > > > > positions are equally weighted, i.e. PositionSize is
defined
> as
> > > 2%.
> > > > > As time moves on, some do very well, and reach, say, a
weight
> of
> > > 3%
> > > > > of equity. When the exit signal arrives, these positions are
> > > replaced
> > > > > by new ones, but now back to the 2% of equity as defined in
> > > > > PositionSize.
> > > > >
> > > > > The resulting problem is that at times I find I have too
much
> cash
> > > > > left. Now, I know that I can rebalance open positions (by
> scaling
> > > > > in/out, for example via TJ's code
> > > > > http://www.amibroker.com/kb/2006/03/06/re-balancing-open-
> > > positions/).
> > > > > However, apart from the extra costs involved, I have found
> that
> > > there
> > > > > is no way to determine/access the amount of cash BEFORE
> > > > > entering/rebalancing the new positions. In other words,
> bo.Cash
> > > gives
> > > > > you the amount of cash "at the end of the bar". You can, of
> > > course,
> > > > > use the amount of cash of the previous bar, but you keep
> lagging
> > > the
> > > > > actual trades.
> > > > >
> > > > > In short, I would like to force the backtester to always
make
> the
> > > > > system fully invested (except for round lots, etc.) It
would
> be
> > > > > great, for example, if there would be an option to
> automatically
> > > > > assign the amount of cash which becomes available from the
> first
> > > > > exited trade to the first new trade, etc. In my system this
is
> > > very
> > > > > applicable, as I always have other trades to replace the
> exited
> > > one.
> > > > >
> > > > > Any thoughts/suggestions welcome. If none, I'll forward
this
> to
> > > > > support.
> > > > >
> > > > > Thx.
> > > > >
> > > > > PS
> > > > >
> > > > >
> > > > >
> > > > > 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/
|