How to prevent reentry on the same candle when using ApplyStop

Hi all,
I am facing a problem with reentries when a stop profit is reached and the buy condition is met on the same bar.
I can only think of a much more complicated solution than simply setting one or two Amibroker options at the beginning of my code but I don't find anything.

ApplyStop(stopTypeLoss, stopModePercent, 1, 1, ValidFrom = 0);
ApplyStop(stopTypeProfit, stopModePercent, 0.3, 0, ValidFrom = 0);



Buy = Low < Ref(High, -1) AND High >= Ref(High, -1) AND Ref(C > EMA(C,10), -1);
BuyPrice = Ref(High, -1);
Sell = 0;

This is the QQQ chart of August this year. The circled candle closed 1.3% higher than the previous one, reaching the stop profit but also the buy condition is met so Amibroker shows another buy at the previous high price, which, of course, leads to a false trade entered due to the fact that Amibroker is "seeing the future".

Does somebody know an easy solution for this?
Thanks
Regards.

First, even without any issues around the stops, your code is peeking into the future. Your entry price is the previous bar's high, which means you are trying to model an intrabar entry. However, your Buy conditions reference both the current bar's Low and High, and those cannot be determined until the end of the bar. You also have not accounted for opening gaps.

If you're trading a universe of stocks, this strategy may be untradeable. Search the forum for posts on Limit Orders for an explanation of why this could be an issue.

The problem with your ApplyStop calls is that AmiBroker does not use named parameters like Visual Basic and some other languages. All parameters values are assigned based on their position. Therefore, doing this:

ApplyStop(stopTypeLoss, stopModePercent, 1, 1, ValidFrom = 0);

is exactly the same as this:

ApplyStop(stopTypeLoss, stopModePercent, 1, 1, 0);

You've assigned the fifth parameter (Volatile) a value of 0. You have not assigned any value to the ValidFrom parameter, which is in the 7th position, so AmiBroker will simply use the default value (0) for that parameter.

You should be able to get the behavior you want by correctly using the ReentryDelay and ValidFrom parameters.

2 Likes

Hello mradtke,
Thanks for the reply.

I was mistaken regarding this. Since Amibroker does not complain, I thought it is possible.

Regarding my code looking into the future, I guess I haven't understoood you well there but it is not true.
If you set a stop limit order to buy at previous day's high before market open and the low of today does not get below that price, the order won't be filled. If the high of today does not get above previous day's high, the order won't be filled either.
Different topic is if you need to account for a limit price being higher than the stop price. I just wanted to simplify the code for the question.
Under these conditions, I don't care either if there are opening gaps. The buy price will not vary, that is what the condition of the low of today lower than previous day's high is there for.

Thanks again for the response.
Best regards.

What if OPEN is > REF(H, -1) ?

If you send a stop limit order, the order won't be filled until the limit price is reached. So it does not matter if OPEN > REF(H, -1).

Stop-Limit Orders

A Stop-Limit order is an instruction to submit a buy or sell limit order when the user-specified stop trigger price is attained or penetrated. The order has two basic components: the stop price and the limit price. When a trade has occurred at or through the stop price, the order becomes executable and enters the market as a limit order, which is an order to buy or sell at a specified price or better.

1 Like

Besides ApplyStop have RE-ENTRY delay parameter that you should use.

It is recommended to carefully read the manual:

https://www.amibroker.com/f?applystop

And you have to pass ALL ARGUMENTS in the order they are specified in the users' manual. Don't skip arguments. AFL is like C, not like python. Order of arguments is important and must follow the guide.

Thanks for the reply.
I tried to simplify my issue and I suspect I misled you and @mradtke.

My problem is actually when I use something like that on a universe of stocks.
I tried to symplify the question mentioning only QQQ but on one symbol, it is not a problem.
For example, taking the 11 U.S. SPDR sectors:

ApplyStop(stopTypeLoss, stopModePercent, 1, 1, False, 1, 1);
//	ApplyStop(stopTypeProfit, stopModePercent, 0.3, 0, False, 1, 0);
ApplyStop(stopTypeProfit, stopModePercent, 0.3, 0, False, 1, 1);



Buy = Low < Ref(High, -1) AND High >= Ref(High, -1) AND Ref(C > EMA(C,10), -1);
BuyPrice = Ref(High, -1);
Sell = 0;

SetOption("MaxOpenPositions",1);
PositionScore = Random();

The problem is this:

On the same day:
The position XLI is closed at the close (as it should) but the position in XLC has been opened as a breakout above yesterdays high.
So the position in XLC is going to be open before the one in XLI is closed, which is not correct.

I cannot seem to find any solution, which is not by resorting to the backtester to handle entries and exits on the same bar without going beyond the max positions of the portfolio and using FOR loops to handle stop profit or loss.
That is why I was hoping, there is a parameter of the type "SetOption" that can solve that.

Thanks
Regards

Perhaps SetOption("SettlementDelay", 1) will take care of the problem for you.