Order Filling and HFT Simulation

The Fill variable supports several modes for simulating naive or realistic order filling, as well as a HFT simulation mode. HFT (High Frequency Trading) is a trading method that exploits inefficiencies on the millisecond or microsecond time scale. It is very different to normal algorithmic trading. Usual trading accessories such as candles or indicators, are not used. The deciding factor is speed. HFT systems do normally not run on a trading platform - even Zorro would be not fast enough - but are directly programmed in a high speed language, such as C, Pentium assembler, shader language (HLSL) or hardware design language (VHDL).

Zorro can be used for testing HFT systems in Fill mode 8. In this mode, only direct trading, receiving price quotes, and plotting data are supported; indicators, series, or the run function are not used. Use the main function for initializing the system and for looping through bars. The maximum number of bars must be set up with MaxBars. Trades are opened and closed only with enter and exit commands; TMFs, limits, stops or targets are not used in HFT mode. Hedge mode must be 2. Price quotes are entered to the system with the priceQuote function. Any price quote must include the exchange time stamp, since the system is synchronized to it. The two-way latency between exchange and PC location is set up with OrderDelay and determines the price quote at which the enter or exit order will be filled.

An introduction into HFT testing with Zorro, and an example of a HFT system can be found on Financial Hacker.

For determining the latency of your system, make sure that your PC clock is exactly in sync with the clock used at the exchange, then compare the exchange time stamp of incoming live price quotes with the arrival time stamp. Double this time for getting the roundtrip latency and add the reaction time of your hardware and software. As a rule of thumb, the time stamp difference is about 1 ms per any 300 km distance to the exchange (light travels at 300.000 km/sec), plus about 1..2 ms additional delay due to signal routing. OrderDelay can be set up with a precision of 1 microsecond. Price quote data by data vendors has usually a precision of 1 ms.


Determines how order fills are simulated in [Test] and [Train] mode and how orders entries affect other open trades.


0 Naive order filling. Trades open or close at the current market price or at their Entry, Stop, or TakeProfit limits, regardless of latency, slippage, or intrabar price movement. Accidental 'cheating' - generating unrealistic profits - is possible by modifying stop or profit limits in a TMF. This mode can be used for special purposes, such as comparing Zorro results with 'naive' results by other platforms.
1 Realistic order filling (default). Trades open or close at the most recent price quote plus Slippage or Penalty. When Slippage and Penalty are 0, this mode simulates a latency-free connection to the market that immediately reacts on any price quote. If an entry or exit limit is hit and no Penalty is set, the position is filled at a price replicating live trading as accurate as possible with a slight pessimistic bias (see details below). 'Cheating' is not possible. With daily bars, this mode simulates trading right before the market closes.
3 Delayed order filling. Trades open or close at the next price quote plus Slippage or Penalty. With daily bars, this mode simulates trading at the market open price of the next day.
8 HFT fill mode. Trades open or close at the entered priceQuote whose time stamp is most recent to the current time plus OrderDelay. This mode can be used to simulate the effect of a script-defined latency.





function run()
  BarPeriod = 1440;
  Fill = 3; // enter trades at next day's open 

HFT simulation framework:

// Simulate a stock trading HFT system

#define LATENCY  2.5   // simulate 2.5 milliseconds latency

typedef struct QUOTE {
  char  Name[24];
  var  Time,Price,Size;
} QUOTE; // Quote struct by the NxCore plugin

int callback(QUOTE *Quote) // called by the plugin
  static int Counter = 0; // quote counter
  if(0 == (++Counter % 1000)) { // every 1000 quotes...
    if(!wait(0)) return 0; // check if [Stop] was clicked
  asset(Quote->Name+1); // NxCore adds "e" to the asset name
// trade algorithm here, generate TradeSignalLong/Short
  if(!(NumOpenLong+NumPendingLong) && TradeSignalLong) {
  } else if(!(NumOpenShort+NumPendingShort) && TradeSignalShort) {
  return 1;

function main()
  if(Broker != "NxCore") {
    quit("Please select NxCore plugin!");

  StartDate = 20170103;
  EndDate = 20170131;
  LookBack = 0;
  OrderDelay = LATENCY/1000.;
  Hedge = 2;
  Fill = 8;
  Lots = 1;
  Verbose = 3;

// process the NxCore history tape files, one for each day
  login(1);	// for initilizing the plugin
  int NxDate;
  for(NxDate = StartDate; NxDate = EndDate; NxDate++) {
    string NxHistory = strf("History\\NxTape%8d.nx2",NxDate);
    printf("\nProcessing tape %s..",NxHistory);
    if(!wait(0)) break; // check if [Stop] was clicked

See also:

enter, exit, Hedge, Slippage, Penalty, mode, priceQuote


► latest version online