First you need to understand how AmiBroker works.
- AmiBroker works on the concepts of Bars
- One Bar size depends on what timeseries duration you are using
- Example, if you are using 1-minute frequency; then each 1-minute of prices is 1 Bar (or 1 Candle)
- However, a Bar or Candle can be made up of multiple ticks
- So when a signal is generated in AmiBroker; it will always remain active for every tick in that Bar or Candle
- Note: Whether it will remain active or not also depends on how your code is generating the signal. For example, if you use simple moving average crossover, then you will observe that the signal is active till the Bar ends.
Let us understand this with an example:
- Assume you are using a 1 minute candle
- And at 11:00:30 am, we get a signal (Note: there are still 30 seconds left for the candle to complete)
- AmiBroker keeps the signal active for every live price (tick) that comes after this point until the candle is complete
- Because the signal remains active your code keeps on calling placeOrder*() function
Now, it is the responsibility of the AFL developer to make sure that a placeOrder*() function is only invoked once for a Bar or Candle (most widely traded scenario). But most of the developers (being from trading background) are not an expert in AFL programming. Hence they simply call placeOrder() function whenever signal is present, so identical repeat orders end up being fired. In above example, you will see same order being placed multiple times for every live price that comes between 11:00:30 am to 11:01:00 am.
Please understand that this is not AutoTrader API problem. Because your AFL code is executing placeOrder() function multiple times, so orders will be placed multiple times.
Solution for beginners
We have added a parameter in our afl Avoid repeat orders (in seconds). You can set it’s value higher than your candle period, so for example if you are using a 1-minute (60 seconds) candle then set the value of this parameter to 61 seconds. If you are using 5-min (300 seconds) candle, then set it to 301 seconds. You can press (Ctrl+R) on a chart to bring up parameters menu. Also make sure that the validate parameter passed to placeOrder() function is set to 1 or True.
This does not prevent placeOrder() function from executing multiple times, but the placeOrder() function performs a validation to ignore repeat orders for number of seconds configured. You can see it in the logs, it will place an order on first execution, and remaining execution for same signal will show validation failure (order will not be fired).
How system determines a duplicate order?
The system will consider the order as duplicate, when following conditions are met:
- Order is placed with validate flag set to True in placeOrder() function
- Back to back orders with the same SYMBOL and same TRADE TYPE (within the “avoid repeat delay time” set in parameters)
- There are only 4 possible scenarios that are considered as duplicate. When back to back order have exactly same Trade Type:
- BUY -> BUY
- SELL -> SELL
- SHORT -> SHORT
- COVER -> COVER
- There are only 4 possible scenarios that are considered as duplicate. When back to back order have exactly same Trade Type:
If you want to look at the code of the validation, then look inside autotrader-api.afl for a function with name isDuplicateSignal().
Solution for advanced users
Make sure that the validate parameter passed to placeOrder() function is set to 0 or False.
Modify your IF conditions in such a way that the placeOrder() function is invoked only once. Also you can use our debug guide to test your code, before running it in live market.
You can make use of static variables to check whether order was placed or not. This is because value of a static variable does not automatically change on every execution of a the strategy. Our validation check does this, see more details in autotrader-api.afl (look for a function with name isDuplicateSignal()).
Debug
A developer should always look at the logs that are printed by the AutoTrader AFL library. For more details, read debugging.
Avoid repeat orders (in seconds) a cool function for trading on time bars. Please provide similar function to avoid repeat orders from Range/Tick/Volume Bars with an aim to fire only one order per bar.
April 22, 2020 at 1:57 amThat functionality has nothing to do with time bars. Just look at the in included files.
April 23, 2020 at 3:45 pm