You should be running your backtest over many days/bars, not just one day.
--- In [email protected], "sancra01" <sancr...@...> wrote: > > OK I tried that but I'm getting no difference in my backtest results. > > I noted a day (prior to making the change) that had an Entry signal in > orginal backtest results. I then made the change to the Artificial Future bar > and ran a backtest on the day before. I don't see the entry signal (Open Long > or Open Short) for the next day in my backtest report. > > If I manipulate the following from ... > > SetTradeDelays( 0, 0, 0, 0 ); > > ... to ... > > SetTradeDelays( 1, 1, 1, 1 ); > > ... then I see changes in the report but I still don't get a signal for > tomorrow. > > I'm not sure that making changes to the SetTradeDelays will work as I control > exit and entry times further down in the code. > > Should I be concentrating on solving this as a backtest or an exploration? > > > --- In [email protected], "re_rowland" <rowland@> wrote: > > > > Without looking at your code... > > > > Try going to Backtester Settings: Portfolio: and then enable Add artificial > > future bar (allows to see tomorrow's trade picks) > > > > Then run your AFL as a Backtest instead of an Exploration. > > > > --- In [email protected], "sancra01" <sancra01@> wrote: > > > > > > Hi > > > > > > I'm hoping someone out there in AmiBroker land might be able to provide > > > some guidance. > > > > > > I've spent the last few months learning AFL and have slowly put together > > > the code to backtest a system for which I have almost 30 years of actual > > > trades. The system has 10 different patterns for trading a single > > > instrument. I've followed previous examples on the AmiBroker forum of > > > trading different patterns on a signal instrument and have replicated the > > > instrument data for the 10 patterns so that AmiBroker thinks I'm trading > > > 10 different instruments and will permit me to take multiple signals on a > > > single day (or allow me to take additional signals on subsequent days if > > > I'm still in a trade). You may notice in my AFL below that there are 16 > > > signals. This is because two of these patterns may provide entry signals > > > up to three days in a row. > > > > > > The backtest results mirror the actual trades almost 100% so I think I've > > > got the backtesting AFL code sorted out (although I'm sure there could be > > > room for improvement). The problem I'm now having is that I cannot seem > > > to create an Exploration that will ... > > > > > > 1. Generate Broker orders based on setups - all of the orders in this > > > system are next day orders but are only triggered if some criteria is met > > > (e.g. the instrument price is able to rise 80% of yesterday's trading > > > range from today's open). So if the system signals a setup then an order > > > would be produced that I could forward to my broker. > > > > > > 2. For each day I'm in the trade I'd like a report detailing what trades > > > I'm in and what the stopProfit and stopLoss should be for each day > > > (although in this system stopProfit and stopLoss values don't change once > > > in the trade. Other systems (e.g. the Turtle system) would see these > > > values change on a daily basis and I would have to send through modified > > > orders to my broker). > > > > > > I've worked through some different ideas but I don't seem to be getting > > > anywhere. I was hoping that in an exploration I would be able to do a > > > similar thing that I do in the backtest code below where I can cycle > > > through each bar of data, check all the signals at that bar and pick the > > > highest priority signal(s) but to date I've had no luck. I can produce an > > > array for the setups for each instrument but I have no idea how to > > > manipulate those setup signals as I do in my backtest code below. To > > > assist anyone who may be able to help I've included the following below > > > ... > > > > > > 1. System.afl (the main afl code) > > > 2. Signal 2's Trade afl > > > 3. Signal 2's Setup afl (real setup has been replaced with simple setup) > > > 4. Signal 2's Entry afl (real entry has been replaced with simple entry) > > > 5. Signal 2's Exit afl > > > > > > I tend to use a lot of #include statements so that my code is logical, > > > modular and possibly reusuable across systems and so that I can easily > > > separate out the setups, entries and exits which should also assist in > > > the creation of an exploration. > > > > > > Can anyone provide me with some guidance? Perhaps a technique in > > > AmiBroker I'm not familiar with. I'm not after the full answer just an > > > idea that might get me over the line. > > > > > > Many thanks in advance. > > > > > > Craig > > > > > > P.S. - happy to provide further information if my ramblings above are > > > unclear. > > > > > > > > > > > > ++++++++++++++++++++++++++++++++++++++++++++++++ > > > > > > System.afl > > > > > > // Initialise all backtesting/optimisation options to a default value. It > > > also > > > // serves as a reference check to make sure that all of the factors have > > > been > > > // accounted for. > > > #include <Functions\BoilerPlate.afl>; > > > > > > // DateNum <---> Rata Die conversion - required by Signal 1.afl > > > // The Rata Die.afl was originally included from within the Signal 1.afl > > > but it generated errors > > > #include <Functions\Rata Die.afl>; > > > > > > // Initialise Money Management options > > > initialisedMoneyManagementOptions = False; > > > initialEquity = 10000; > > > #include <Money Management\Fixed Ratio.afl>; > > > > > > SetTradeDelays( 0, 0, 0, 0 ); // No trade delays for entry or exit. Entry > > > and exit times controlled in code below > > > SetOption( "MaxOpenPositions", 8 ); > > > > > > if( Name() == "AP-01 - Signal 1" ) > > > { > > > #include <Trade\System\Signal 1.afl>; > > > } > > > > > > if( Name() == "AP-02 - Signal 2" ) > > > { > > > #include <Trade\System\Signal 2.afl>; > > > } > > > > > > if( Name() == "AP-03 - Signal 3" ) > > > { > > > #include <Trade\System\Signal 3.afl>; > > > } > > > > > > if( Name() == "AP-04 - Signal 4" ) > > > { > > > #include <Trade\System\Signal 4.afl>; > > > } > > > > > > if( Name() == "AP-05 - Signal 5" ) > > > { > > > #include <Trade\System\Signal 5.afl>; > > > } > > > > > > if( Name() == "AP-06 - Signal 6" ) > > > { > > > #include <Trade\System\Signal 6.afl>; > > > } > > > > > > if( Name() == "AP-07 - Signal 7" ) > > > { > > > #include <Trade\System\Signal 7.afl>; > > > } > > > > > > if( Name() == "AP-08 - Signal 8" ) > > > { > > > #include <Trade\System\Signal 8.afl>; > > > } > > > > > > if( Name() == "AP-09 - Signal 9" ) > > > { > > > #include <Trade\System\Signal 9.afl>; > > > } > > > > > > if( Name() == "AP-10 - Signal 10" ) > > > { > > > #include <Trade\System\Signal 10.afl>; > > > } > > > > > > if( Name() == "AP-11 - Signal 11" ) > > > { > > > #include <Trade\System\Signal 11.afl>; > > > } > > > > > > if( Name() == "AP-12 - Signal 12" ) > > > { > > > #include <Trade\System\Signal 12.afl>; > > > } > > > > > > if( Name() == "AP-13 - Signal 13" ) > > > { > > > #include <Trade\System\Signal 13.afl>; > > > } > > > > > > if( Name() == "AP-14 - Signal 14" ) > > > { > > > #include <Trade\System\Signal 14.afl>; > > > } > > > > > > if( Name() == "AP-15 - Signal 15" ) > > > { > > > #include <Trade\System\Signal 15.afl>; > > > } > > > > > > if( Name() == "AP-16 - Signal 16" ) > > > { > > > #include <Trade\System\Signal 16.afl>; > > > } > > > > > > SetCustomBacktestProc( "" ); > > > SetBacktestMode( backtestRegularRawMulti ); > > > if( Status("action") == actionPortfolio ) > > > { > > > bo = GetBacktesterObject(); // Get backtester object > > > > > > AB = CreateObject( "Broker.Application" ); // Required to sort > > > Automatic Analysis results by date > > > AA = AB.Analysis; // Required to sort Automatic Analysis results by > > > date > > > > > > bo.PreProcess(); // Do pre-processing > > > > > > /* > > > System permits a maximum of one new long and one new short > > > position per day with one exception. > > > Every Signal 1 position must be taken. Therefore it's possible to > > > enter a maximum of three new > > > positions per day ... > > > > > > 1. A Signal 1 position > > > 2. A long position (other than Signal 1) > > > 3. A short position > > > > > > To apply the above rules we must cycle through every bar, examine > > > each entry signal generated > > > and either accept or reject it depending on these rules. This is > > > done in the following code ... > > > > > > */ > > > > > > for( i = 0; i < BarCount; i++ ) // Loop through all bars > > > { > > > entrySignalCountLong = 0; // Reset entry signal count (long) > > > variable > > > entrySignalCountShort = 0; // Reset entry signal count (short) > > > variable > > > > > > currentEquity = bo.Equity; > > > > > > for( sig = bo.GetFirstSignal(i); sig; sig = bo.GetNextSignal(i) ) > > > { // Loop through all signals at this bar > > > > > > if( sig.IsEntry() ) > > > { // Only interested in entry signals to determine whether > > > we accept/reject the signal > > > > > > if( sig.Type == 1 ) // Long entry signal > > > { > > > entrySignalCountLong++; > > > > > > if( sig.Symbol == "AP-01 - Signal 1" ) > > > { // If current signal is a Signal 1 then we > > > decrease the entrySignalCountLong variable > > > entrySignalCountLong--; > > > } > > > > > > for( trade = bo.GetFirstOpenPos(); trade; trade = > > > bo.GetNextOpenPos() ) > > > { // Loop through all open positions at this bar > > > > > > // ++++++++++++++++++++++++ Need to explain what > > > we're doing here +++++++++++++++++++++++++++++ > > > > > > if( ( sig.Symbol == trade.Symbol ) AND > > > ( sig.Symbol == "AP-08 - Signal 8" OR > > > sig.Symbol == "AP-09 - Signal 9" OR > > > sig.Symbol == "AP-14 - Signal 14" OR > > > sig.Symbol == "AP-15 - Signal 14" ) ) > > > { > > > sig.Price = -1; > > > entrySignalCountLong--; > > > } > > > > > > } > > > > > > } > > > > > > if( sig.Type == 3 ) // Short entry signal > > > { > > > entrySignalCountShort++; > > > > > > for( trade = bo.GetFirstOpenPos(); trade; trade = > > > bo.GetNextOpenPos() ) > > > { // Loop through all open positions at this bar > > > > > > // ++++++++++++++++++++++++ Need to explain what > > > we're doing here +++++++++++++++++++++++++++++ > > > > > > if( ( sig.Symbol == trade.Symbol ) AND > > > ( sig.Symbol == "AP-03 - Signal 3" OR > > > sig.Symbol == "AP-04 - Signal 4" ) ) > > > { > > > sig.Price = -1; > > > entrySignalCountShort--; > > > } > > > > > > } > > > > > > } > > > > > > if( entrySignalCountLong > 1 ) > > > { // If entrySignalCountLong > 1 then all other long > > > signals except Signal 1 should be ignored > > > > > > switch( sig.Symbol ) > > > { > > > case "AP-07 - Signal 7": > > > sig.Price = -1; > > > case "AP-08 - Signal 8": > > > sig.Price = -1; > > > case "AP-09 - Signal 9": > > > sig.Price = -1; > > > case "AP-10 - Signal 10": > > > sig.Price = -1; > > > case "AP-11 - Signal 11": > > > sig.Price = -1; > > > case "AP-12 - Signal 12": > > > sig.Price = -1; > > > case "AP-13 - Signal 13": > > > sig.Price = -1; > > > case "AP-14 - Signal 14": > > > sig.Price = -1; > > > case "AP-15 - Signal 15": > > > sig.Price = -1; > > > case "AP-16 - Signal 16": > > > sig.Price = -1; > > > default: > > > break; > > > } > > > > > > } > > > > > > if( entrySignalCountShort > 1 ) > > > { // If entrySignalCountShort > 1 then all other short > > > signals should be ignored > > > > > > switch( sig.Symbol ) > > > { > > > case "AP-02 - Signal 2": > > > sig.Price = -1; > > > case "AP-03 - Signal 3": > > > sig.Price = -1; > > > case "AP-04 - Signal 4": > > > sig.Price = -1; > > > case "AP-05 - Signal 5": > > > sig.Price = -1; > > > case "AP-06 - Signal 6": > > > sig.Price = -1; > > > default: > > > break; > > > } > > > > > > } > > > > > > #include <Money Management\Fixed Ratio.afl>; > > > > > > } > > > > > > } // End of for loop over signals at this bar > > > > > > bo.ProcessTradeSignals(i); > > > > > > } // End of for loop over bars > > > > > > bo.PostProcess(); // Do post-processing > > > > > > AA.SortByColumn( 2, False, False ); // Sort Automatic Analysis > > > results by date > > > > > > } > > > > > > > > > ++++++++++++++++++++++++++++++++++++++++++++++++ > > > > > > AFL code for Trade\System\Signal 2.afl ... > > > > > > ShortPrice = Open; // Ensure trade entry is Market On Open (setting > > > override in Automatic Analysis | Backtest Settings | Trades) > > > > > > Buy = 0; > > > Sell = 0; > > > Short = 0; > > > Cover = 0; > > > > > > #include <Setup\System\Signal 2.afl>; > > > #include <Entry\System\Signal 2.afl>; > > > > > > Short = Ref(Setup,-1) AND Entry; > > > > > > #include <Exit\System\Signal 2.afl>; > > > > > > > > > ++++++++++++++++++++++++++++++++++++++++++++++++ > > > > > > AFL code for Setup\System\Signal 2.afl ... > > > > > > Setup = ( DayOfWeek() == 1 ); // Example setup > > > > > > > > > ++++++++++++++++++++++++++++++++++++++++++++++++ > > > > > > AFL code for Entry\System\Signal 2.afl ... > > > > > > Entry = ( DayOfWeek() == 2 ); //Example entry > > > > > > > > > ++++++++++++++++++++++++++++++++++++++++++++++++ > > > > > > AFL code for Exit\System\Signal 2.afl ... > > > > > > stopProfit = 0; > > > stopLoss = 0; > > > barsInTrade = 0; > > > > > > for( i = 1; i < BarCount; i++ ) > > > { > > > if( barsInTrade == 0 AND Short[ i ] ) // If not in trade and > > > current bar signals a short > > > { > > > stopProfit = Open[ i ] - 1; // Tuesday's open minus one point > > > stopLoss = Open[ i ] + 1; // Tuesday's open plus one point > > > barsInTrade = 1; // The buy day becomes bar 1 > > > } > > > > > > if( barsInTrade >= 2 AND Open[ i ] <= stopProfit ) // Trade held > > > longer than one day and open is less than or equal to stopProfit > > > { > > > Cover[ i ] = 1; // Cover > > > CoverPrice[ i ] = Open[ i ]; // Cover at open price > > > stopProfit = 0; // Reset variables > > > stopLoss = 0; // Reset variables > > > barsInTrade = 0; // Reset variables > > > } > > > > > > if( barsInTrade >= 1 AND High[ i ] >= stopLoss ) // High is > > > greater than stop loss - cover trade > > > { > > > Cover[ i ] = 1; // Cover > > > CoverPrice[ i ] = IIf( Open[ i ] > stopLoss, Open[ i ], > > > stopLoss ); // Cover at open or stopLoss (whichever is higher) > > > stopLoss = 0; // Reset variables > > > stopProfit = 0; // Reset variables > > > barsInTrade = 0; // Reset variables > > > } > > > > > > if( barsInTrade >= 1 ) > > > { > > > barsInTrade++; > > > } > > > } > > > > > >
