The same goes with HandleStops.
----- Original Message -----
Sent: Monday, September 21, 2009 1:40
PM
Subject: [amibroker] Re: Support
Issues
Unfortunately, no. None of my questions are answered by this otherwise
excellent document (which I have already read many times).
Perhaps my questions were not clearly expressed in the help request. But
basically I want to know:
- When should we use bo.UpdateStats(bar, 0)
- When should we use bo.UpdateStats(bar, 1)
- When should we use bo.UpdateStats(bar, 2)
- When should we use bo.HandleStops(bar)
The author of the document that you pointed to seemed equally confused.
When describing usage of UpdateStats he says:
"The AmiBroker help is a little vague on how the TimeInsideBar parameter
works"
He then goes on to say:
"why it would be called with the value set to zero or more than
once, I'm not sure."
In other words, he had the exact same questions that I have now.
Further, after much experimentation, I must question his conclusions on when
and where to use HandleStops(), at least as it applies to more recent versions
of AmiBroker.
I have put togeather a sample Optimization, below, for a "percent
of equity" position sizing that runs once for each of:
-
default high level AmiBroker backtester
-
low level backtester template described in the UKB document that
you pointed to
-
low level backtester using my own best guess at how these calls should
be made.
If you (or anyone else) run it, you will see that my own best guess
appears to match the default AmiBroker behavior. The UKB template (as I've
understood it) does not match at all. I would like to get confirmation (or
correction) that my conclusions are accurate. My conclusions are spelled out
as comments in the code.
For the purposes of this example, I am running a Long only
strategy, using AmiBroker version 5.26.5 beta, Norgate Premium Data for the
period Jan 1/08 - Dec 31/08 on a watchlist containing:
I am exagerating the position size to force scenarios where we run out of
cash. The script can also be Backtested with default optimization argument set
to 3 in order to see _TRACE statements in an AA Window "Detail Log" style
report of the sfclimbers trades.
Here is the code:
// Simplify the example by disabling
most of the variables that effect
// position size when expressed
as a percentage of equity.
SetOption("AccountMargin", 100);
SetOption("AllowPositionShrinking",
false);
SetOption("CommissionMode", 2);
SetOption("CommissionAmount", 0);
SetOption("InterestRate", 0);
SetOption("MinShares", 1);
SetOption("MinPosValue", 0);
// These two options have a direct impact
on low level backtest,
// far beyond what was covered
in the otherwise excellent UKB document.
// Run
this optimization once for each of the 4 combinations of these
two
// options using a watchlist of AAPL, IBM,
ORCL, MSFT from 1/1/08 - 12/31/08.
SetOption("UsePrevBarEquityForPosSizing",
true);
SetOption("ActivateStopsImmediately",
true);
// Simple random entry followed by N-bar
stop.
SetOption("InitialEquity", 500000.00);
SetTradeDelays(0, 0, 0, 0);
SetPositionSize(33,
spsPercentOfEquity);
Buy = Random(13000) > 0.5;
BuyPrice =
Open;
Sell = 0;
ApplyStop(stopTypeNBar, stopModeBars, 3,
0);
// Use optimizer to
generate output for each of default AB, UKB and
//
sfclimbers speculation. At a minimum it will illustrate that the
// UKB article is incomplete and/or out of date. Whether or
not the
// sfclimbers conclusions are correct is the subject of
this help request!
custom = Optimize("Custom",
3, 1, 3,
1);
SetCustomBacktestProc("");
if
(Status("action") == actionPortfolio) {
maxPosition =
0.33; // Must match call
to SetPositionSize above
marginMultiplier = 100 / GetOption("AccountMargin");
usePreviousBar = GetOption("UsePrevBarEquityForPosSizing");
activateStopsImmediately = GetOption("ActivateStopsImmediately");
dates =
DateTime();
bo =
getBacktesterObject();
switch (custom) {
case 1: {
// Default AmiBroker behavior
bo.Backtest();
break;
}
case 2: {
// User knowledge base template behavior
bo.PreProcess();
for (bar = 0; bar < BarCount; bar++) {
size
= bo.Equity * maxPosition;
quit
= 0;
for (sig = bo.GetFirstSignal(bar); sig; sig =
bo.GetNextSignal(bar)) {
if (sig.IsEntry()) {
lotSize
= int((size / sig.Price)
/ RoundLotSize) *
RoundLotSize;
if (bo.Cash >= ((lotSize *
sig.Price) / marginMultiplier) && quit == 0) {
sig.PosSize
= -2000 - lotSize;
}
else if (bo.Cash > 0 && quit == 0) {
sig.PosSize
= 0; // Insufficient
funds. Cancel signal.
quit
= 1;
}
else {
sig.PosSize
= 0; // Already hit
insufficient funds. Cancel remaining signals.
quit++;
}
if (sig.PosSize <
0) {
bo.EnterTrade(bar,
sig.Symbol, sig.IsLong(), sig.Price, sig.PosSize);
}
}
else if (sig.IsExit()) {
bo.ExitTrade(bar,
sig.Symbol, sig.Price);
}
}
bo.HandleStops(bar);
bo.UpdateStats(bar,
1);
bo.UpdateStats(bar,
2);
}
bo.PostProcess();
}
case 3: {
// sfclimbers behavior
bo.PreProcess();
for (bar = 0; bar < BarCount; bar++) {
_TRACE(DateTimeToStr(dates[bar]) +
"\t" + bar);
/*
*
Conclusion 1:
* Must consult UsePrevBarEquityForPosSizingand call updateStats(bar, 0)
*
to get initial equity.
*/
if (!usePreviousBar) {
bo.updateStats(bar,
0); // Update to bar
open.
baseEquity
= bo.Equity; // Then calculate
equity
}
else {
baseEquity
= bo.Equity; // Calculate
equity
bo.updateStats(bar,
0); // Then update to
bar open.
}
size
= baseEquity * maxPosition;
_TRACE("\tBase Equity: " + baseEquity +
", Opening Equity: " +
bo.Equity + ", Pct. of Base: " + size + ", Starting Cash:
" + bo.Cash);
/*
*
Conclusion 2:
*
Must process regular exit signals at start of each bar, before new entries.
*
*
Conclusion 3:
*
Must consult ActivateStopsImmediately to determine whether to additionally
*
process stops at start of each bar, before new entries.
*/
for (sig = bo.GetFirstSignal(bar); sig; sig =
bo.GetNextSignal(bar)) {
if (sig.IsExit() && (sig.Reason == 1 ||
!activateStopsImmediately)) {
if (pos = bo.FindOpenPos(sig.Symbol)) {
msg
= "\tExit (" +
sig.Reason + ") " +
WriteIf(sig.IsLong(),
"Long: ", "Short: ") + sig.Symbol +
", Shares: " + pos.Shares;
/*
* Conclusion 4:
* Must call updateStats(bar, 1) after each trade entry or exit in order
* to have up to date Equity and Cash data.
*/
bo.ExitTrade(bar,
sig.Symbol, sig.Price);
bo.UpdateStats(bar,
1);
_TRACE(msg + ", Cash Balance: " + bo.Cash);
}
}
}
quit
= 0;
for (sig = bo.GetFirstSignal(bar); sig; sig =
bo.GetNextSignal(bar)) {
if (sig.IsEntry()) {
lotSize
= int((size / sig.Price)
/ RoundLotSize) *
RoundLotSize;
if (bo.Cash >= ((lotSize *
sig.Price) / marginMultiplier) && quit == 0) {
sig.PosSize
= -2000 - lotSize;
}
else if (bo.Cash > 0 && quit == 0) {
sig.PosSize
= 0; // Insufficient
funds. Cancel signal.
quit
= 1;
}
else {
sig.PosSize
= 0; // Already hit
insufficient funds. Cancel remaining signals.
quit++;
}
if (sig.PosSize <
0) {
msg
= "\tEnter " +
WriteIf(sig.IsLong(),
"Long: ", "Short: ") + sig.Symbol +
", Price: " + sig.Price
+ ", Shares: " +
abs(sig.PosSize +
2000) + " Margin Loan: " + (abs(sig.PosSize + 2000) * sig.Price) * (1 - (1 /
marginMultiplier));
result
= bo.EnterTrade(bar, sig.Symbol, sig.IsLong(), sig.Price, sig.PosSize);
bo.UpdateStats(bar,
1);
_TRACE(msg + ", Cash Balance: " + bo.Cash +
" Result: " + result);
}
else if (quit == 1) {
_TRACE("\t" + sig.Symbol + " not entered because of insufficient funds");
}
}
}
/*
*
Conclusion 5:
*
Must consult ActivateStopsImmediately to determine whether to process stops
*
at end of each bar, after new entries.
*/
if (activateStopsImmediately) {
for (sig = bo.GetFirstSignal(bar); sig; sig =
bo.GetNextSignal(bar)) {
if (sig.IsExit() && sig.Reason != 1) {
if (pos = bo.FindOpenPos(sig.Symbol)) {
msg
= "\tExit (" +
sig.Reason + ") " +
WriteIf(sig.IsLong(),
"Long: ", "Short: ") + sig.Symbol +
", Shares: " + pos.Shares;
bo.ExitTrade(bar,
sig.Symbol, sig.Price);
bo.UpdateStats(bar,
1); // Update running
stats after each trade.
_TRACE(msg + ", Cash Balance: " + bo.Cash);
}
}
}
}
/*
*
Conclusion 6:
*
HandleStops is obsolete and should no longer be called.
*/
msg
= ", Ending Cash: " + bo.Cash;
bo.UpdateStats(bar,
2);
_TRACE("\tEnding Equity: " + bo.Equity + msg);
}
bo.PostProcess();
break;
}
}
}
Try with each of the following combinations (make changes in the
code). The UKB template will always be wrong:
UsePrevBarEquityForPosSizing:
true, ActivateStopsImmediately:
true
UsePrevBarEquityForPosSizing:
true, ActivateStopsImmediately:
false
UsePrevBarEquityForPosSizing: false, ActivateStopsImmediately: true
UsePrevBarEquityForPosSizing: false, ActivateStopsImmediately:
false
Any attempt at low level custom code cannot be trusted until somebody
can actually write low level custom backtester code that can be verified
against AmiBroker built in code. I want to experiment with non trivial
position sizing. But, I can't do it without a better description of how the
low level backtester is supposed to be used.
I will send this note to support also, if you or Marcin prefer to reply
privately. But, I suspect that any reply would be helpful to the whole
group.
Mike
--- In amibroker@xxxxxxxxxxxxxxx, "Tomasz Janeczko" <groups@xxx>
wrote:
>
> Hello,
>
> In short, all information you
asked for in this particular request can be found on-line:
>
http://www.amibroker.org/userkb/2008/03/16/amibroker-custom-backtester-interface-2/
>
> Best regards,
> Tomasz Janeczko
> amibroker.com
>
----- Original Message -----
> From: "Mike" sfclimbers@xxx
> To:
amibroker@xxxxxxxxxxxxxxx
> Sent: Friday, September 18, 2009 7:17
PM
> Subject: [amibroker] Re: Support Issues
>
>
>
> Well,
> >
> > Since there have been a few others, I
guess I'll add my ticket to the pile, just in case there really is a technical
problem. The
> > address I am registered with is a Yahoo dot com
address.
> >
> > I received an auto reply for my support
request #62580 on Thursday, August 27, 2009. I have not received anything
since then. I
> > sent a follow up status request a week after that.
Again, no reply.
> >
> > I have been checking my spam
folder, but have not noticed anything from AmiBroker in there. Though,
admittedly, I get a lot of
> > spam. So, I may have missed
something.
> >
> > Mike
> >
> > --- In
amibroker@xxxxxxxxxxxxxxx, "Tomasz Janeczko" groups@ wrote:
>
>>
> >> Jeremy,
> >>
> >> I have
instructed Marcin to double check if there is any message from you awaiting
reply.
> >>
> >> Sometimes if there is long exchange
between user and support, it may happen that support
> >>
considers case as resolved, while customer expects some extra info. If this
happens, please just
> >> reply again to any unanswered ticket and
tell the support that you are waiting for specific info.
>
>>
> >> Best regards,
> >> Tomasz
Janeczko
> >> amibroker.com
> >> ----- Original
Message -----
> >> From: "nyctastudent" jberkovits1@
>
>> To: amibroker@xxxxxxxxxxxxxxx
> >> Sent: Friday,
September 18, 2009 3:08 PM
> >> Subject: [amibroker] Re: Support
Issues
> >>
> >>
> >> > TJ,
>
>> >
> >> > There might be an issue on the AmiBroker
side. I am having a problem geting a response to an item I submit on September
2nd.
> >> > Its
> >> > not due to spam filters.
I sent a folow up email on the 17th and still no reply. AmiBroker usually has
the best support in the
> >> > business. Something is causing a
break in support communications. If you need any aditional info from me please
let meknow.
> >> >
> >> > Thanks for a great
product.
> >> >
> >> >
> >> >
Best regards,
> >> >
> >> > Jeremy Berkovits,
CMT
> >> >
> >> > Merc Partners
> >>
> 11 Great Neck Road
> >> > Great Neck, NY-11021
>
>> >
> >> > Direct: (516) 304-3200 EXT. 307
>
>> > Cell: (917) 698-3444
> >> > jberkovits1@
>
>> > AOL IM: jberkovitscmt
> >> > Yahoo IM:
jeremy7827110028
> >> >
> >> >
> >>
>
> >> >
> >> >
> >> > On Wed,
Sep 2, 2009 at 8:42 AM, support@ wrote:
> >> >
> >>
> Hello,
> >> >
> >> > Your message: "GICS
Import File" has been received.
> >> > Ticket number is #62757
(please DO NOT remove it from the subject line when replying).
>
>> >
> >> >
> >> >
> >>
> ------------------------------------
> >> >
>
>> > **** IMPORTANT PLEASE READ ****
> >> > This group
is for the discussion between users only.
> >> > This is *NOT*
technical support channel.
> >> >
> >> > TO GET
TECHNICAL SUPPORT send an e-mail directly to
> >> > SUPPORT
{at} amibroker.com
> >> >
> >> > TO SUBMIT
SUGGESTIONS please use FEEDBACK CENTER at
> >> >
http://www.amibroker.com/feedback/
> >> > (submissions sent via
other channels won't be considered)
> >> >
> >>
> For NEW RELEASE ANNOUNCEMENTS and other news always check DEVLOG:
>
>> > http://www.amibroker.com/devlog/
> >> >
>
>> > Yahoo! Groups Links
> >> >
> >>
>
> >> >
> >>
> >
> >
>
>
> >
> > ------------------------------------
>
>
> > **** IMPORTANT PLEASE READ ****
> > This group is
for the discussion between users only.
> > This is *NOT* technical
support channel.
> >
> > TO GET TECHNICAL SUPPORT send an
e-mail directly to
> > SUPPORT {at} amibroker.com
>
>
> > TO SUBMIT SUGGESTIONS please use FEEDBACK CENTER at
>
> http://www.amibroker.com/feedback/
> > (submissions sent via
other channels won't be considered)
> >
> > For NEW RELEASE
ANNOUNCEMENTS and other news always check DEVLOG:
> >
http://www.amibroker.com/devlog/
> >
> > Yahoo! Groups
Links
> >
> >
> >
>