PureBytes Links
Trading Reference Links
|
Hello,
You somehow mistinterpreted what I wrote. The sentence you are referring to points out that: a) the only reason of existence of
low-level CBT is to implement
your OWN methodology and NOT to reproduce built-in; b) that it requires work on your own
I did NOT say that you are not advanced programmer. The sentence was addressed to *everybody* on the list, not to you directly.
Best regards,
Tomasz Janeczko
amibroker.com
----- Original Message -----
From: "sfclimbers" <sfclimbers@xxxxxxxxx>
To: <amibroker@xxxxxxxxxxxxxxx>
Sent: Monday, September 21, 2009 2:24 PM
Subject: [amibroker] Re: Support Issues
>I received the message from support. Thank you.
>
> As to your comment
>
> "Low-level custom backtester interface is solely for advanced programmers who want to implement/experiment with *their own*
> backtest methodologies completely *different* than built-in one,
> and comes without hand-holding."
>
> If 20 years of professional software development doesn't qualify me as an advanced programmer, then I don't know what will.
>
> If we can't measure our assumptions against a known benchmark (i.e. reproduce the built in behavior), then it becomes much more
> difficult to determine whether we are using the API correctly.
>
> Anyway, your position is clear. I'll work out the rest on my own.
>
> Mike
>
> --- In amibroker@xxxxxxxxxxxxxxx, "Tomasz Janeczko" <groups@xxx> wrote:
>>
>> Hello,
>>
>> You received the answer via support channel.
>>
>> With regards to UpdateStats it is documented quite clearly
>> http://www.amibroker.com/guide/a_custombacktest.html
>>
>> Quote from docs:
>> "UpdateStats( long Bar, long TimeInsideBar )
>>
>> Low-level method that updates equity, exposure, trade excursions (for MAE/MFE calculations) and other internal variables required
>> for correct calculation of statistics. You must NOT use this function in high-level and mid-level approaches. TimeInsideBar
>> parameter specifies intraday time position.
>>
>> TimeInsideBar = 0 means opening of the bar,
>> TimeInsideBar = 1 means middle of the bar,
>> TimeInsideBar = 2 means end of bar.
>>
>> As certain internal calculations depend on end-of-bar calculations, this method must be called once and only once with
>> TimeInsideBar parameter set to 2 at the end of processing of every bar inside in your custom backtesting loop. May be called zero
>> or more times for every bar inside backtesting loop with TimeInsideBar parameter set to 0 (zero) or 1."
>>
>> Whenever you need to read/use any stats (including portfolio equity) on open/in the middle/end of bar you should call UpdateStats
>> with corresponding value. That's all.
>>
>> The same goes with HandleStops.
>> Quote from docs:
>> "HandleStops( long Bar )
>>
>> This low-level method handles automatic stops (applystops). This method MUST NOT be used in high-level and mid-level approaches.
>> In low-level mode you should call this method once for each bar inside trading loop."
>>
>> Low-level custom backtester interface is solely for advanced programmers who want to implement/experiment with *their own*
>> backtest methodologies completely *different* than built-in one,
>> and comes without hand-holding.
>>
>> Best regards,
>> Tomasz Janeczko
>> amibroker.com
>> ----- Original Message -----
>> From: Mike
>> To: amibroker@xxxxxxxxxxxxxxx
>> 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:
>>
>> 1.. When should we use bo.UpdateStats(bar, 0)
>> 2.. When should we use bo.UpdateStats(bar, 1)
>> 3.. When should we use bo.UpdateStats(bar, 2)
>> 4.. 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:
>>
>> 1.. default high level AmiBroker backtester
>> 2.. low level backtester template described in the UKB document that you pointed to
>> 3.. 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:
>>
>> a.. AAPL
>> b.. IBM
>> c.. ORCL
>> d.. MSFT
>> 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@> 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@
>> > 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
>> > >
>> > >
>> > >
>> >
>>
>
>
>
>
> ------------------------------------
>
> **** 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
<*> 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/
|