Question about StateRules and Controls



Recently I’ve been working on revamping our ATDL implementation and came across a particular case where one of the parameters need to be sent only when that parameters checkbox is selected. I’ve tried multiple options/ways to implement this piece but so far no luck. Would it be possible for implementing such feature using ATDL?

Send “Enable Hi-Lo (FIX tag: 9980)” only when “Enable Hi-Lo” check box is selected. Do not send FIX Tag_9980 if the checkbox is not selected.

Sample ATDL:

<?xml version="1.0" encoding="utf-8"?>

With above implementation, I see the checkbox has a defunct state where I always get 9980=N as a wireValue.

Appreciate your help.

Kind regards,


FIXatdl-1 1-Specification_with_Errata_20101221.pdf (1.1 MB)


Thinking quickly vs. thoroughly and perhaps thoughtfully. Its been a long while!

Use a “helper control” ( a screen widget that is disposable and used only on the HCI, not tied to a parameter on the wire; used only during order build, then thrown away). Then use a parameter on the wire that is invisible and optional.

If the helper control changes state, and the state is “Enable Hi-Lo”, then use a state rule to set the value on the wire parameter.

Once an optional parameter has a value it will be sent.

Might be a better solution but that’s what pops into mind.



Main page for FIXatdl on the FIX website:


Hanno - thanks for the link.


Was pulled away on other activities, sorry for the delay, but wanted to get back to you and find out if you got your checkbox / helper control working exactly the way you want it?

Sorry about the brief reference to the docs but wanted you to be sure you had them. Actually you need to study THREE things before things will begin to make sense with FIXatdl: the .pdf is very good but you should also look very carefully at the sample file for examples and it’s in-line documentation. Then you should spend some time looking at the actual .xsd source files themselves because they also carry extensive comments that can also be very helpful. All three of these sources (in the zip file in Hanno’s link), taken together, cover a lot of territory. I find myself using FIND on all three sources yields info that is easy to forget.

RULES are used in two areas. They were created for VALIDATION first, and only later developed and applied to the FLOW area with ample reuse. To make your checkbox and optional parameter on the wire work, you will be in the FLOW area, with the underlying Boolean logic reused from the VALIDATION area.

FLOW is all about user interaction DURING order build. (You can’t assume all parameters are populated yet, the order may only be partly built.) EVENT listeners are attached to controls (widgets) which raise a “change” event. FLOW RULES are fired by those change events. Every time – ANY control(s) containing a listener to a different control that fires – will cause that control’s rule to run. If the logic in that rule then evaluates TRUE, the prescribed change(s) in the state of that specific control will be made. (RULES that fire may cause other RULES to fire too.)

VALIDATION only occurs when the entire order is built, and the user has pressed the “send order button”. It assumes all parameters are filled in, and ready to go. Validation RULES are run all at once, covering all the parameters that are mentioned in the set of rules for that strategy. Here you must “jump over all the hoops” or an ERROR message is given to the user, and the order is not sent until they ALL are resolved.

Validation rules are defined via StrategyEdit elements, child of an entire Strategy Element. (Push send order, that entire strategy is going to be sent and executed, with all the currently standing parameters, UNLESS a StrategyEdit rule fails. Meaning the Boolean result of all the logic in the StrategyEdit rule returns FALSE.

Flow-control rules are defined via StateRule elements, child of a specific control (widget). When the user changes the value of a SINGLE control xxx, all RULES (StateRule) that contain Boolean logic that includes field=”xxx” will be listening for changes on “xxx”, and will run. So a change lay:Control ID=“xxx” may drive changes in 0 or more other Controls, including changing their value, which if bound to a parameter will dive change there too. (keep reading and loop back here if needed).

Each StateRule (FLOW) can only do one or more of:
(1) change the “enabled” state of its parent control to either True or False
(2) change the “visible” state of its parent control to either True or False
(3) change the current VALUE state of its parent control to a supplied value. (a constant string value | an enumID |the special token {NULL}) Note: {NULL} means “uninitiated” in a Control, and if that control is bound to a Parameter, it means OMIT the Parameter from the FIX WIRE message.

StateRules initiate the above change(s) when the underlying Boolean logic returns TRUE.

Admiditedly somewhat confusing: “field=” is used in the Boolean logic portion of both VALIDATION RULES (StrategyEdit) and FLOW RULES (StateRule) but morphs meaning, based on context

  • In StrategyEdit (Validation) rules, “field=xxx” refers to a Parameter name=”xxx”
  • In SateRule (Flow) rules, “Field=yyy” refers to a lay:Control ID=“yyy”

Controls are typically “bound” to Parameters (<lay:Control ID=“aaa” … parameterRef=“bbb”> meaning this Control named “aaa” will have a value that will be bound to the Parameter named “bbb”.

Controls that are not “bound” to Parameters (that lack the parameterRef="bbb” attribute) are referred to as “helper controls”. Their function is to aid the order build (FLOW) process only. They do not supply values that end up on the FIX Wire.

Head spinning yet? Its confusing initially because xml and .xsd can easily look like a pile of spaghetti code with many GOTOs. Work through the three sources a few times (.pdf .xsd and .xml in-file documentation) and things will eventually become a whole lot easier.


PS By using “not and” in the Boolean logic parts of rules you can even do some “computation”. Rules can also be named and reused, called in other rules, etc.




Very helpful screen shots and code snip. Very much appreciated.

Check box controls (widgets) are for the most part 2-state, vs 3-state.

When you called for the checkbox your initValue was set to false. (lay:Control ID=EnableHiLowField … initValue=“false”)

Since your checkbox was bound to a parameter (parameterRef = “EnableHiLo”), “false” from the control drove the value=“unchecked” of that control down to its bound parameter, where there was a matching enumPair for that value, “unchecked”. After that match it put a “N” on the wire. Given your optional Parameter now had a specified value, that Tag=value pair had to be sent.

First thing is to try and see if the checkbox can be rendered WITHOUT specifically initializing it (drop the initValue=“False”) and does that solve it?

Next thing you might try is:

[cut the optional Parameter to only have ONE EnumPair]

<Parameter name = "EnableHiLow" xsi:type "Char_t" fixTag = "9980" use="optional">
    <EnumPair enumID=”sendIt” wireValue=”T”/>

[may need to send a {NULL} token from the control down to the Parameter for the unchecked state.]

<lay:Control ID=”EnableHiLow” xsi:type=”lay:CheckBox_t” label=”Enable Hi Low?” 

May not need the “uncheckedEnumRef={NULL}” as that may be the default state of the bound control? May not need “initValue=“false”” as that may be the default initial state?

May not even need the FLOW rule?



Hi Rick, Hanno,

My apologies for delayed response due to account being on hold for uploading screen shots. Many thanks for your help and providing valuable feedback on my questions. Let me try this and get back in case of any further issues. I’ll keep you posted.

Kind regards,


Hi Rick,

It worked :slight_smile: and as expected. Really appreciate your help on this.

  <lay:StrategyPanel border = "Line" title = "Strategy Parameters" collapsible = "false" orientation = "VERTICAL">
      <lay:StrategyPanel border="None" collapsible = "false" orientation = "HORIZONTAL">
        <lay:StrategyPanel border="None" collapsible = "false" orientation = "HORIZONTAL">
          <lay:Control ID = "EnableHiLoField" xsi:type = "lay:CheckBox_t" label = "Enable Hi-Lo" parameterRef="EnableHiLo" checkedEnumRef="sendIt" uncheckedEnumRef="{NULL}" initValue="false"/>

Kind regards,



Excellent! (Wondered if you needed the StateRule with the change, or if you could drop that?)

Have to admit, FIXatdl is sometimes “clunky”, a bit loosely specified, and at times the naming of elements and attributes might have been more intuitively obvious.

The Algorithmic Trading Working Group will be having a fresh look at the standard in a few weeks, most likely looking to extend the existing schema (so we don’t break standing implementations). To really “clean it all up” would involve wholesale change, top to bottom refactoring, etc, all causing a significant amount of transitional pain.

By all means participate in the algo WG, fresh input is always appreciated.



Hi Rick,
StateRule is not required as per your explanation before.
Also, I would like to know if current ATDL can have a region / country specific checks/validations for certain Strategy parameters? As long as i can see, only Strategies can have a Region specific settings but not Strategy Parameters.

We have certain requirements where Strategy Params are only required for say one of the regions/countries.

Something like this:
IF (Region=“AsiaPacific” & Country=“XX”) THEN {Display “ENABLEHiLo” settings in ATDL screen}

If we have such feature available, then it will be very good to prepare a Global Single ATDL file for all Regions (US/EMEA/APAC), which we provide to our vendors/Clients.

Appreciate your help.

Kind regards,



To do that (region/country-specific rules), you would need to define multiple elements, as each of those can define different region/country/security type-applicability / filtering rules). So, you would effectively ‘clone’ the single strategy into 2+, and define the AsiaPacific one with different check/validation rules.


Hi Scott,
yups, thats what currently we are doing to separate out region specific strategies in ATDL.
Apologies for late reply.

Kind regards,



Wanted to give you some historical prospective on the FIXatdl 1.1 standard (current), but first the conclusion:

WG never anticipated using “classification” data in the rules [ stateRule (FLOW) or StrategyEdit (VALIDATION) ]. That would allow a strategy designed for one particular use to “morph” into a strategy for a different use, something we thought (at least at that time) should be avoided. The WG felt having a “pile” of .xml files would be the better way to go.

Further detail, perhaps relevant to updating

FIXatdl started development in 2006, issued v1.0 (really just a proof of concept) in a few months and then refactored quite a bit and refined, issuing v1.1 in 2010 (proven production ready in multiple OMS systems, C++ and Java open source parsing projects with live code published, broad industry support from the OMS/EMS suppliers and Buy-Side, etc.)

Over the 2006 to 2010 development, features were added at different points:

  • multiple strategies in one file - very early
  • GUI widgets/controls library - very early
  • Validation beyond .xsd - pretty early
  • Total separation of Wire from GUI - middle
  • Cloud pre trade analytics / draft orders - middle
  • UI text can be any language (UTF8), changed easily - pretty late
  • Work Flow - pretty late
  • Rule reuse - pretty late
  • “Classification” aspects - very late

By classification aspects I mean the “tags” that are useful to a buy-side trader/portfolio manager team when faced with a trading desire, and a “box of FIXatdl” files that are supplied to them by various Sell-Side algo providers. Things that might help in the purchase decision… (Thank Scott when you see him for really putting some thought and real OT into this area at the 11th hour just before FIXatdl v1.1 shipped.)

  • element name=“Regions” (TheAmericas | AsiaPacificJapan | EuropeMiddleEastAfrica)
  • element name=“Country” (ISO 3166 country code)
  • element name=“Markets” (ISO 10383 MIC Code)
  • element name=“SecurityTypes” (ISO 10962 CFI Code)
  • simpleType name=“Language” (ISO 639-1 language)

Early on, the WG concluded that global brokers had separate “glass houses” for IT in each of three locations (TheAmericas | AsiaPacificJapan | EuropeMiddleEastAfrica). Global brokers were typically formed by regional acquisition and total IT integration typically lagged. There was considerable concern that algos from the same firm, with the same name (e.g. VWAP) might be implemented differently in a different region (subtle differences in UI, FIX parameter use, regulatory schemes, etc.). The most simple solution was a separate FIXatdl file for each region.

Some notes on FIXatdl file proliferation & management

WG noted early on that as the complexity of the .xsds rose, the difficulty of writing code for OMS/EMS systems rose exponentially, particularly when you added debugging, unit and functional testing. To be successful in the market you need broad OMS/EMS uptake. Writing a set of FIXatdl compliant .xml files for one firm is a breeze vs. writing a OMS/EMS FIXatdl parser that must work with all compliant .xml files that are supplied to it, now and into the future, from different firms and different authors.

WG estimated times to work with FIXatdl files for the sell side:

  • Learning time reading the standard pdf, studying the standard .xsd files, studying the way things work in the .xml sample file, (going back and forth between all three sources), experimenting with how things work, becoming accustom to how elements are named, setting up your .xml editor / IDE to work with FIXatdl, learning the ISO standards, etc. About 40 hours
  • Time to write first .xml file for production use (after above) About 4-8 hours. (not including testing).
  • After some experience, time to write a typical algo strategy, into an .xml file, of average complexity, typically reusing many parts of other working / tested strategies: 1 hour or less.
  • Time for an “administrative assistant” to take an English language file, extract all the text that hits the UI, and supply that to a translator: 15 minutes or less. After skillful language translation, time to insert the foreign language translations: 15 minutes or less. XML expertise: Zero.

Estimated time to write a FIXatdl parser and integrate it to a standing OMS/EMS system: 30-90 days, starting with open source code libraries.

When FIXatdl 1.1 launced in 2010 there were a number of firms working with FIXatdl editors, file databases, etc. Some started with a master database of the firm-wide FIX parameters and every algo they produced parameters. They also had tracked all the firm’s buy-side OMS/EMS “internals” (because many would extend FIXatdl, particularly in the highly proprietary “look and feel” of their UI. A few firms were offering FIXatdl “hubs” or “portals” where authorized buy sides could fetch out the latest sell side FIXatdl files.

So…lots to ponder when we soon go “under the hood” and look towards updating.

Some of the decisions the WG reached back in 2006-2010 regarding the algo “industry” are likely totally obsolete today.