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