-
Notifications
You must be signed in to change notification settings - Fork 8
Tablature User Guide for Messages
Here is how to write rules of engagement in markdown in a way that will be processed by md2orchestra to produce an Orchestra file.
You should write an overview of your rules of engagement starting with heading level 1, as designated by a single "#". The md2orchestra utility uses the top-level heading as the title of your Orchestra file, and it watches for the keyword "version" in the heading. If present, it will set the produced Orchestra file version to the word that follows the keyword, in this example "1.0".
You may follow the heading with any number of paragraphs that describe the rules of engagement. Recall that markdown separates paragraphs with an extra linefeed.
The description of the rules of engagement may be followed by a table of metadata terms to identify your document. It tells the what, when, and who issued the rules of engagement. The table has two columns, Term and Value. The terms are defined by and industry standard called Dublin Core Terms for media identity. The core terms are: "contributor", "coverage", "creator", "date", "description", "format", "identifier", "language", "publisher", "relation", "rights", "source", "subject", and "type".
Here's and example of a document overview with metadata:
# Rules of Engagement version 1.0
Order messages and their elements.
| Term | Value |
|-----------|---------------------------------------|
| title | Orchestra Example |
| publisher | FIX Trading Community |
| rights | Copyright 2020, FIX Protocol, Limited |
| date | 2020-06-09T16:09:16.904-06:00 |
Sections of your rules of engagement are identified by a heading at level 2 or lower starting with one of the following keywords: Actor, Codeset, Component, Fields, Flow, Group, Message, StateMachine, or Variables. Matching is case insensitive, but the keyword must be the first word in the heading.
Below each section heading, you may provide any number of paragraphs of explanation. The paragraphs may include markdown marks for emphasis, such as italic or bold. Markdown lists may also be included. Tablature treats lists the same as regular paragraphs.
Fields are defined in a markdown table as shown below. The md2orchestra program matches these required column headers: Name, Tag, Type, and these optional headers: Scenario, Values, and Documentation. (Heading matching allows you to present the columns in any order that you wish. Column heading match is case insensitive.)
- Name is the humanly readable name of a field (required if tag is missing or no reference file is used)
- Tag or ID is the numeric ID of a FIX field (required if name is missing or no reference file is used)
- Type is either a FIX datatype such as int or String, or the name of a codeset that enumerates the valid values of a field. (required)
- Scenario is a use case name. For fields, different use cases of a field may link to different codesets. For example, PartyRole used in an ExecutionReport may have a richer set of values than is required in inbound orders. Scenario is not required; if not supplied, a default scenario "base" is encoded in Orchestra.
-
Values column can provide a list of valid values. Each value must be in the format
code = name
. Whitespace separates the codes from each other. Alternatively, a codeset can be named and provided as a separate table (see below). - Encoding optionally tells the character encoding of character or string fields.
- ImplMinLength, ImplMaxLength, or implLength set the limits of string fields.
Documentation for a field will be embedded in the resulting Orchestra file. See Documentation below for details.
It is not necessary to be fussy with alignment of markdown table columns but makes it more humanly readable if it is close to alignment. The rightmost "|" bar character in each row is not required; a line break will suffice.
## Fields
| Name | Tag | Type | Scenario | Values | Documentation |
|--------------|----:|--------------|----------|------------------|---------------|
| Side | 54 | Sides | inbound | | Side of order
| OrdType | 40 | char | inbound | 1=Market 2=Limit | Order type
| MyUserDefined1 | 6234| UTCTimestamp | | | A timestamp
In this example, codesets are defined in two different ways. For field Side (54), the type of the field is given as "Sides", the name of a codeset defined elsewhere. On the other hand, OrdType (40) has its codeset defined implicitly by listing valid values in the Values column. The resulting structures in Orchestra will be the same format—a field definition with reference to a codeset definition.
The advantage of defining a codeset separately is that it can be reused by any number of fields. For example, SecurityIDSource and LegSecurityIDSource can point to the same set of possible values. Also, by explicitly defining a codeset, you can document each code and give more details, as opposed to the Values short cut in a fields table.
Each codeset is introduced by providing a heading at level 2 or below. It must begin with the keyword "Codeset". The second word is interpreted as the name of the codeset. The name must be unique within the resulting Orchestra file, and it is best if you stick to FIX standard names (assuming your ROE is using FIX protocols). Thereafter are a couple of optional keys. One is the datatype of the codeset, following keyword "type". In the example below, the datatype of the codes is "char", short for character. Type should exactly match a FIX datatype. If you do not provide the type, md2orchestra will assume "char" by default, but newer codesets in FIX are generally defined as "int", short for integer.
The last key of a codeset is "scenario", a use case name. This allows a distinction between sets of codes used in different message scenarios. In this example, the scenario is "inbound". Potentially, a different set of codes is used for side in outbound messages. (In Orchestra, the default scenario name is "base". For simplicity, the tool does not require or output the default name.)
Additional words may be included in the heading, so long as the required ones are present, and the keyword and name are the first two words.
As with other sections, any number of paragraphs may be provided between the heading and the table to explain the codeset.
## Codeset Sides type char scenario inbound
Side of an order
| Name | Value | Documentation |
|----------|-------|---------------|
| Buy | 1 | |
| Sell | 2 | |
| Cross | 8 | Cross (orders where counterparty is an exchange, valid for all messages *except* IOIs) |
| Opposite | C | "Opposite" (for use with multileg instruments) |
A component block is a building block that may be reused in any number of message definitions. A component can contain fields, other components, and repeating groups.
You define a component first by providing heading that starts with the keyword "Component" followed by the name of a component. Optionally, this can be followed by "scenario" and a use case name. If scenario is not declared, a default will be used in the Orchestra file.
Any number of paragraphs of documentation can follow the heading.
Then create a table as shown below that lists the members of the component. Members may be fields, other components or repeating groups.
The required column headings are Name, Tag, and Presence, and one optional column named Values.
- Name is the humanly readable name of a member
- Tag is the numeric ID of a FIX field
- Presence tells the disposition of the member within the component. Presence must be one of the following keywords:
- Required—the member must be present
- Optional—the member may be present
- Constant—the field always has a constant value
- Forbidden—the member must not be present
- Ignored—the member may be present, but it is not validated
- Scenario is the scenario name of a member. The member scenario may or may not be the same as the component scenario name. (Not shown in this example.)
- Values is used for either a constant field (presence="constant") or as an implicit codeset. Codesets in a component table work the same as in a fields table, example shown above.
For fields, either name or tag or both may be provided. For nested components and repeating groups, the name is required. See the Messages example below for how to nest components and groups. The presence keywords may be abbreviated, e.g. "req" for "required". If not declared, presence defaults to optional.
## Component Instrument scenario inbound
The `Instrument` component block contains all the fields commonly used to describe a security or instrument.
| Name | Tag | Presence | Values |
|------------------|----:|-----------|--------|
| SecurityID | 48 | required | |
| SecurityIDSource | 22 | constant | 8 |
A repeating group is defined the same way as a component, except that you use the keyword "Group", and you must include a NumInGroup field as the first member.
## Group Parties scenario inbound
The Parties component block is used to identify and convey information on the entities both central and peripheral to the financial transaction represented by the FIX message containing the `Parties` Block.
| Name | Tag | Presence | Values |
|----------------|----:|-----------|--------|
| NoParties | 453 | | |
| PartyID | | req | |
| PartyIDSource | | opt | |
| PartyRole | | req | 1=ExecutingFirm 2=BrokerOfCredit
An actor is participant in a service. An actor may send or receive messages or do both. Each stream of messages is called a flow.
The heading for actor starts with the keyword "Actor" and is just followed by a name.
An actor may have state variables. They keep the state of a service independent of messages that are sent back and forth. State variables follow a heading with the keyword "Variables", and are presented in the same format as the members of a component.
Actor example with state variables. In this example, the actor has a trade date and trading status of various instruments.
## Actor Market
### Variables
| Name | Tag | Presence |
|---------------------------|-------|----------|
| TradeDate | 75 | required |
| SecurityMassTradingStatus | 1679 | required |
| SecMassStatGrp | group | required |
An actor may also have one or more state machines. A state machine captures a finite number of possible states of a business entity, e.g. market phases or order status. An entity can transition from one state to another, but generally only certain transtions are allowed. For example, an order cannot change from Canceled state back to PendingNew. Canceled is a final state of an order; once dead it cannot be brought back to life. So valid transitions are enumerated explicitly along with all possible states.
A state machine is introduced by a heading with the keyword "StateMachine" followed by a name.
The required column headings in a state transtion table are State, Transition, and Target, while Documentation is optional. For each transition, State is current state before the transtion, and Target is new state after the transtion. The intial state of an entity should be listed first.
Example of a state machine:
### StateMachine MarketPhase
Phases of the market as a state machine
| State | Transition | Target | Documentation |
|----------|------------|----------|-------------------------------------------|
| Closed | Reopening | Preopen | |
| Halted | Resumed | Preopen | Authorities resume a market after a halt. |
| Open | Halting | Halted | |
| Open | Closing | Preclose | |
| Preopen | Opened | Open | |
| Preclose | Closed | Closed | |
A flow is a unidirectional stream of messages between actors. A message type belongs to a flow. There is no limit to the number of flows in a service.
A flow has name but no other identifiers in its header. Below the header is a small table giving the source and destination of the flow. The source and destination must match a defined actor name.
Example with two flows:
## Flow OrderEntry
| Source | Destination |
|---------|-------------|
| BuySide | Market |
## Flow Executions
| Source | Destination |
|--------|-------------|
| Market | BuySide |
A message is a complete data unit that is sent on a flow from one actor to another.
All possible message identifiers that may appear in a heading:
Word | Contents |
---|---|
"Message" | "Message" keyword and name are required and must be at the beginning of the heading. |
(name) | Required, message name |
"type" | Optional |
(MsgType) | Follows "type" if present, value of MsgType (35) |
"scenario" | Optional |
(scenario) | Follows "scenario" if present, scenario name defaults to "base" otherwise |
"flow" | Optional |
(flow) | Follows "flow" if present, flow on which this message is sent |
(id) | Message numeric ID in parentheses |
Members of a message are formatted in a table in similar fashion to a component. To include a component block in a message, list the component by name and put "component" in the Tag column. The keyword may be shortened to "comp" or even "c". Similarly, a group may be included by putting "group" or shortened form into the Tag column.
Message heading and structure example:
## Message NewOrderSingle type D flow OrderEntry (14)
The new order message type is used by institutions wishing to electronically submit securities and forex orders to a broker for execution.
| Name | Tag | Presence | Scenario |
|----------------|----:|----------|----------|
| StandardHeader | c | required | |
| ClOrdID | 11 | required | |
| Account | | | |
| Instrument | c | | inbound |
| Side | | required | inbound |
| Price | | | |
| StopPx | | required | |
| OrderQtyData | c | required | |
| OrdType | | required | |
| MyUserDefined1 | | | |
| MyUserDefined2 | 6235| | |
| Parties | g | | inbound |
The workflow section tells the possible responses to a message type. In the Tablature style, it must have a heading at level 3 or lower starting with the keyword "Responses". You may add text after that keyword, but md2orchestra picks up the message identifiers from the higher level heading above that starts with the keyword "Message".
The message responses are listed in a table like the one show below. The Name, Msgtype, and Scenario columns identify the response message. Name is required while Msgtype is optional and Scenario defaults to "base". The When column contains a Score DSL expression that determines when each response applies. When the expression evaluates to true, then that response message is sent. See the Orchestra documentation for the Score syntax.
### Responses
| Name | Msgtype | When | Documentation | Scenario |
|-----------------------|---------|---------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------|----------|
| ExecutionReport | 8 | $Market.SecMassStatGrp[SecurityID==in.SecurityID].SecurityTradingStatus != ^TradingHalt and $Market.Phase == "Open" | | |
| ExecutionReport | 8 | $Market.Phase == "Closed" | | rejected |
| BusinessMessageReject | j | !exists $Market.SecMassStatGrp[SecurityID==in.SecurityID]" | | |
| ExecutionReport | 8 | $Market.SecMassStatGrp[SecurityID==in.SecurityID].SecurityTradingStatus != ^TradingHalt and $Market.Phase == "Open" | One or more fills may occur; the first one may be synchronous. | traded |
Most tables support documentation of an element. Table headings may be Synopsis, Elaboration, Example, or Display to set an Orchestra documentation element with the corresponding purpose
attribute, or simply Documentation to be set without a specific purpose value.
The tool md2orchestra parses a markdown document to generate an Orchestra repository file. A reference Orchestra file (e.g. from a FIX Extension Pack) can be provided to allow the omission of tag numbers or names where applicable. The tool will automatically look up missing values and populate the resulting Orchestra file accordingly. If a field is referenced in a message definition, the tool will copy the field definition to the resulting Orchestra file even if the md2orchestra user did not type it in.
The reverse tool is called orchestra2md. It supports a roundtrip between text and Orchestra. It extracts information from an existing Orchestra file and writes it out as a markdown document. In fact, an easy way to start the cycle is to use a published Orchestra file representing the latest FIX standard and use orchestra2md to create an initial markdown file. Then delete material not needed for your rules and engagement--erasing is easier than typing from scratch. Then edit what changed, and use md2orchestra to create the first draft of your Orchestra file.