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;





Reply via email to