[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [amibroker] Re: Support Issues



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/