> 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
> > >
> > >
> > >
> >
>