I am encountering a problem while trying to enter at open and sell at close of the same bar. To make things clear, I have created a simple code below. No special setting on settings window as well that could complicate the behaviour
The intention of the code above is straightforward. Just to make it clear - buy at open when yesterday's close is less than last 10 days' moving average. sell if close is greater than open.
A scan obviously shows all signals as I expect, but the backtest simply skips many trades even if signals are there.
If you run the above afl on any instrument and any timeframe, you will see stunning results and you will understand what I mean..
Can someone throw light on what needs to be done so that backtest shows the intended result? I believe it must be some setting that I need to make active, but I can not figure out which..
thanks. I did try that. That was the first thing I tried But that did not help to figure out what was going on behind.
Did you try to run the above code?
Yes, but without the full formula (and/or your "default" settings) it makes not a lot of sense for me; for instance, using my current general configuration, a lot of trades are simply skipped due to insufficient funds.
Insufficient funds are okay and intended. This is done by settlementdelay. It is a way to prevent future leaks i.e it prevents taking position until funds are available again as sell happens at close while buy happens at open. ( you will see your 'returns' are much larger if you remove the line that sets settlementdelay.)
The code that I provided can be considered complete. the settings are done through Allowsamebarexit and settlementdelay.
Just for completeness am including the settings too. Note that buyprice /sellprice/'allow same bar exit' are explicitly set in AFL. I used qqq as symbol, but you can use any instrument you have
@amiuser some possible ideas to try. I think your Trade Delays are incorrect. If I understand your strategy, the signal is generated at the Close of current bar. You want to Buy on the next bar Open
SetTradeDelays( 1, 0, 0, 0);
Also your code will generate repeated Buy signals even if a Sell has not occurred so consider,
Buy = ExRem(Buy, Sell);
And you wrote
So you are using Daily bars. But your settings you show 30 minute bars?
I haven't tested those changes but I think they are worth a look.
Signal is generated based on previous bar ( 30 minute / daily actually does not matter to show the point I wanted to ). In the shown code I have used Ref -1 and setting buyprice to current open. Having said that I have tried setradedelays(1,0,0,0) as well (in conjunction with removing Ref). That did not work as well. i.e same impossible results.
Exrem i have read that should not be used in conjunction with same bar exits. ( I can also confirm that as I tried that too)
may be put in another way, how should the afl be written to get the backtest result the intended way
i.e buy at open whenever previous bar's close is less than previous 10 day moving average of close and sell whenever (including current bar ) close is greater than open.
is slightly different buy logic as current bar close is compared to a calculated value that does not use current bar.
In any case even if i use your suggestion, the amazing results (slighly different statistic due to changed buy logic) from backtest still persists.. When you get a chance, please run the code on any instrument/timeframe and see. I guess some future leak is happening.
I suspect the sell condition of c > o together with allowsamebarexit is causing the strange behaviour and am pretty sure am missing something trivial here.. just cant figure what it is!
i know but the problem is that it 'seems' random and mostly takes only the trades that are profitable skipping several losing trades. I get a very good performance no matter what instrument/timeframe i take and always a CAR/MDD that is too attractive and too good to be true which tells me that there is some future leak. Does anyone else not get amazing returns with the posted AFL running on any symbol/timeframe?
Btw did you run the code and see the performance figures? It is a holy grail Jokes apart, it is a case of future leak., but I just can not figure out how it happens in this code
It’s your trade delays and buyprice variable. Your buying at the open of a bar when it close above a MA. You don’t know the level of that MA until the bar closes, so your looking forward. Set tradelay as recommended before. You’ll buy the next bars open price which is not forward looking.
Be very careful with buy price and sell price logic.
SetOption( "AllowSameBarExit", True );
SetOption( "MaxOpenPositions", maxpos = 1 );
Buy = Close < MA( Close, 10 );
Sell = Close > Open ;
Short = Cover = 0 ;
SetTradeDelays ( 1, 0, 0 , 0 ) ;
BuyPrice = Open;
SellPrice = Close;
RoundLotSize = 0 ;
SetBacktestMode( backtestRegularRaw ) ;
SetCustomBacktestProc( "" );
if( Status( "action" ) == actionPortfolio )
{
bo = GetBacktesterObject(); // Get backtester object
bo.PreProcess(); // Do pre-processing
PosQty = 0;
for( i = 0; i < BarCount; i++ ) // Loop through all bars
{
// Open Positions the bar Open :
available = maxpos - PosQty ; // calculate the number of new position you can open
size = ( bo.Cash - 10 ) / available ; // calculate positions size leaving ~$10 in cash
for( sig = bo.GetFirstSignal( i ); sig; sig = bo.GetNextSignal( i ) )
{
if( sig.IsEntry() )
{
if( available )
{
bo.EnterTrade( i, sig.Symbol, sig.IsLong(), sig.Price, size );
available --;
}
}
}
// Porcess exits and count the number of remaining open positions at the bar close:
PosQty = 0 ;
for( pos = bo.GetFirstOpenPos; pos ; pos = bo.GetNextOpenPos() )
{
ExitSignal = bo.FindSignal( i, pos.Symbol , 2 ) ;
if( ExitSignal )
{
// exit at the close
bo.ExitTrade( i, pos.Symbol, ExitSignal.Price );
}
else
{
PosQty ++;
}
}
bo.UpdateStats( i, 1 ); // Update MAE/MFE stats for bar
bo.UpdateStats( i, 2 ); // Update stats at bar's end
} // End of for loop over bars
bo.PostProcess(); // Do post-processing
}
well, am sure there should be a way to do it by CBT. I just took your code and ran and yes, all good and results are horrible as anyone can expect when there is no future leak!
I have designed dozens of strategies with amibroker that are live on markets over the years, but keeping it simple has been a priority. I have never ever had to use CBT.
Other amibroker experts, can someone explain why the original code (or the underlying logic) does not work on normal backtest?
Kind of played around with it a bit tonight. Don't usually fool around too much with same bar entry/exits.
Scratched my head for a bit but after looking up "SettlementDelay" , the manual recommends using backtestregularraw.
Blockquote
SettlementDelay - this option describes the number of days (not bars) it takes for sale proceeds to settle and be available for opening new positions.
SetOption("SettlementDelay", 3 ); // this will cause that proceeds from sale are only available for trading on 3rd day after sale
For detailed tracking " Detailed log" report option now shows available and unsettled funds for T+1, T+2 and so on
Note: when using this option it is recommended to use backtestRegularRaw instead of backtestRegular, otherwise some trades may not be entered because funds are not settled immediately and you need to be able to enter not on first but subsequent buy signals and that is exactly what backtestRegularRaw offers.
Note2: old backtester (Equity() function) ignores settlement delay
The behavior I was noticing was trades would close on an up candle as expected but then re-entry was allowed on same bar at the open. So everytime a trade closed, a new trade started on a guaranteed up candle as funds we're available. So it was guaranteeing an up candle, plus using funds that shouldn't be available so its leveraged.
With backtestregularraw set. "Settlement Delay" would not allow re-entry until funds we're settled. And the results went to crap as expected.
Note to self. Mixing same bar exits, and defining buyprice/sellprices cant get complicated.