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" <rowl...@...> 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++; > > } > > } > > >
