Simulating order fills is a crucial part of any backtesting process. This is also a reasonably complex process - at least if the results are to be accurate.
As such, the AWTS data protocol APIs include a specific endpoint (SimFill()
); to put the onus on fill simulation on the data module itself. This is for three main reasons:
For example, the dataoanda
data module provides data from Oanda, an FX/CFD broker. Oanda market data includes spreads, and the API reports down to S5 (five second) candles. Therefore the dataoanda
module can accurately and rapidly determine whether and when a given order would fill.
Conversely, Polygon.io are a data vendor and do not act as a broker. The datapolygon
module can rapidly simulate fills, but should be fed spread/slippage information with the request to improve accuracy.
If you use the AWTS execution engine, this all happens automatically and you don't need to do anything yourself; the act of your strategy placing an order will result in a best effort simulated fill that the engine will take care of for you.
To use it manually, you can use the CLI tool or the AWTS APIs - see the examples below.
Note a positive quantity signifies a Buy, a negative quantity for a sell. Zero quantity is invalid.
The order type can be market
, limit
, stoploss
or takeprofit
. Other order types (e.g. multi-legged/complex orders, "market if touched" orders, OCO/bracketed orders, etc) are not supported yet, but will be added in a future iteration for modules where the upstream broker supports such functionality in actual trading.
::tip In practise, when using SimFill() you may not always wish to use the result; your strategy can can subsequently decide to just ignore it; e.g. to 'cancel' the order. The point of simulating in one call is to avoid having to make multiple re-checks to the data on every tick asking "have you filled yet?"; just do it once and keep hold of the result. ::
The AWTS CLI tool provides a simple command-line mechanism for testing fills, in a fashion that can be included in shell scripts or other automations. This is also the quickest/simplest way to explore the functionality.
Here is an example of simulating a fill on the instrument with symbol OANDA:NATGAS_USD
(a Natural Gas CFD), for a limit
order placed at 2023-06-14T17:13:03Z
for 1
unit at a limit price of 2.15
:
❯ awts data simfill OANDA:NATGAS_USD 2023-06-14T17:13:03Z limit 1 2.15
Symbol: OANDA:NATGAS_USD
Filled
At 2023-12-13T06:51:12Z after 4357h38m9s
At price 2.153
The result showed that such an order would fill at 2023-12-13T06:51:12Z
- i.e. after ~181 days! And it would fill at a price of 2.153.
For making SimFill()
requests via the APIs please see the API documentation.
Complex order rules (e.g. OCO, Market-if-touched, etc) and broker-specific feature extensions to order behavior are not currently supported.