Thanks, Mike. What you just explained is currently a bit over my head, but at least now I have a direction - and more stuff to learn! Dang, it never ends...
--- In [email protected], "Mike" <[EMAIL PROTECTED]> wrote: > > I suspect that the problem is that your code is not doing any kind of > array manipulations at all. Instead, you have written a manual loop > that stuffs result values into the Buy array simply as storage, then > hands that to the backtester. > > The backtester cannot change the manual logic that you used to > populate that array. Therefore, the only thing that the backtester can > do is trim the entries that are not in the date rage. > > Had you used array manipuations (e.g Sell = ExRemSpan(Buy, bars)) then > the backtester would have been able to align all the arrays involved > and do the work for you. > > So, you have two choices: > > 1. Rewrite your code using array manipulations. > > 2. Change your manual loop logic to only operate on the range > specified in the AA window. See the Status function (e.g. barinrange) > for how to do that: > > http://www.amibroker.com/guide/afl/status.html > > Mike > > > --- In [email protected], "ozzyapeman" <zoopfree@> wrote: > > > > This is a weird problem. It has become apparent to me that the > > backtester is not adhering to the specified date range. > > > > For example, I have a simple Forex test system that Buys on the > first > > bar, and sells when there is 100 pips profit, or 5 days have elapsed > > (loss). Then it re-enters the trade on the next available bar. So > there > > should be a Buy at the very first bar. But when I backtest on a > date > > range like 6/21/2007 - 7/21/2007, the first Buy occurs on 6/26/2007, > > instead of 6/21. > > > > It was very basic AFL and I could not find any flaw in logic. So > someone > > advised me to install Debug View and add trace statements. > > > > What I found is that the backtest engine is going all the way back > to > > the begining of my actual database (April 1998) and applying the > AFL, > > but only showing me results post 6/21/2007. The "phantom" Buys and > Sells > > that occur prior to 6/21/2007 makes the backtester think it is > already > > in a trade when it officially starts on 6/21. And it's only when the > > "phantom" Sell occurs on 6/26 that it shows the first official Buy > on > > that date in the backtester trade report. > > > > How could this be? > > > > Any help much appreciated. > > > > Below is the code with all the backtester settings. Please ignore > the > > trace statements. They are only for debugging. As you can see, the > code > > is very basic, (for testing purposes only): > > > > > > > > > ////////////////////////////////////////////////////////////////////// > //\ > > /////////////// > > // > > // SIMPLE TEST SYSTEM: > > // > > // BUY AT FIRST BAR, THEN SELL AT 100 PIPS PROFIT OR AFTER 7200 > > ONE-MINUTE BARS (5 DAYS). > > // RE-ENTER ON THE NEXT BAR AFTER A SELL. > > // > > > ////////////////////////////////////////////////////////////////////// > //\ > > ////////////// > > > > // > > -------------------------------------------------------------------- > --- > > // Variables > > // > > -------------------------------------------------------------------- > --- > > > > Profit = 0.0100; > > bars = 7200; > > maxContractsPerPair = 1; > > maxPairsTraded = 1; > > Slippage = 0.0002; > > > > > > // > > -------------------------------------------------------------------- > --- > > // BackTester Settings > > // > > -------------------------------------------------------------------- > --- > > > > tradeDelay = 1; > > > > SetBarsRequired(10000, 10000); // Ensures that > the > > charts include all bars AND NOT just those on screen > > SetOption("AccountMargin", 100); // Account margin, > 100 > > = no margin > > SetOption("ActivateStopsImmediately", False); // Intraday stops > ? > > SetOption("AllowPositionShrinking", False); // Take partial > > trades if equity available ? > > SetOption("AllowSameBarExit", True); // Allow same bar > exit > > for profit stops ? > > SetOption("CommissionAmount", 4.00); // Commission > amount > > SetOption("CommissionMode", 3); // 3 = $ per > > share/contract > > SetOption("FuturesMode", 1); // = use > MarginDeposit > > and PointValue in calculations > > SetOption("InitialEquity", 100000); // Initial equity > $ > > SetOption("InterestRate",0); // Set interest > rate > > earned for free cash, zero to evaluate system > > SetOption("MaxOpenPositions", maxPairsTraded * maxContractsPerPair); > > SetOption("MinPosValue", 0); // Min position > value > > to make trade worthwhile, 0 = no limit > > SetOption("MinShares", 1); // Min number > shares > > SetOption("PriceBoundChecking", False ); // Price to stay > in > > bar range ? > > SetOption("ReverseSignalForcesExit", False); > > SetOption("UsePrevBarEquityForPosSizing", True ); // Use last known > bar > > for position sizing ? > > SetTradeDelays(tradeDelay, tradeDelay, tradeDelay, tradeDelay); > > SetPositionSize(1, spsShares); > > > > if (maxContractsPerPair > 1) > > SetBacktestMode(backtestRegularRawMulti); > > > > // In AmiBroker, make sure that Symbol Information is properly set > up > > for each pair, esp. currency field. > > // Also, under AmiBroker main menu, make sure to set Tools --> > > Preferences --> Currencies for each pair > > > > RoundLotSize = 1; > > MarginDeposit = 2000; > > PointValue = 100000; > > > > // > > -------------------------------------------------------------------- > --- > > // Trading System Formula > > // > > -------------------------------------------------------------------- > --- > > > > BuyPrice = Open + Slippage; > > ShortPrice = Open - Slippage; > > SellPrice = Open - Slippage; > > CoverPrice = Open + Slippage; > > > > > > // Set up some variables to give us info on current position > > wasLong = reachedProfitLevel = buySignal = sellSignal = > barToExitLong = > > 0; > > > > // Set up variables for our entry values, as our stops will test > against > > the initial entry prices > > valueAtBuy = Null; > > profitLevel = Null; > > > > // Number of open contracts > > longContractCount = 0; > > > > // Debugging arrays > > dateArray = DateNum(); > > timeArray = TimeNum(); > > > > for (i = 0; i < (BarCount-TradeDelay); i++) > > { > > // Remember if a position is currently open, so we do not re- > enter in > > the same direction on the same bar > > wasLong = longContractCount > 0; > > > > // Check for conditions to exit a long trade > > if (longContractCount > 0) > > { > > reachedProfitLevel = C[i] > profitLevel; > > > > if (reachedProfitLevel) > > { > > _TRACE("bar=" + i + " " + StrFormat("%06.0f",dateArray[i]) > + " " > > + StrFormat("%06.0f",timeArray[i]) + " reached long ProfitLevel"); > > sellSignal[i] = 3; // 3 = profit : this behavior emulates > the > > Equity(1) functionality > > longContractCount = 0; > > } > > > > // Sell at loss > > else if ( i == barToExitLong) > > { > > _TRACE("bar=" + i + " " + StrFormat("%06.0f",dateArray[i]) + > " " + > > StrFormat("%06.0f",timeArray[i]) + " reached barToExitLong"); > > sellSignal[i] = 2; // 2 = max loss : this behavior emulates > the > > Equity(1) functionality > > longContractCount = 0; > > } > > } > > > > // Long entry > > if ( NOT wasLong ) > > { > > _TRACE("bar=" + i + " " + StrFormat("%06.0f",dateArray[i]) + " > " + > > StrFormat("%06.0f",timeArray[i]) + " not was long"); > > buySignal[i] = 1; > > longContractCount = 1; > > valueAtBuy = BuyPrice[i+tradeDelay]; > > profitLevel = valueAtBuy + Profit; > > barToExitLong = i + bars; // 5 days later > > } > > } > > > > // This logic is needed to workaround strange undocumented > backtester > > behavior when the sell/cover arrays are non-boolean. > > Sell = sellSignal != 0; > > Buy = buySignal; > > >
