Multiple Imports

In this section we describe the mechanism available in IPL for importing multiple imports. While this is possible this should be considered a potentially risky operation since there are necessary side-effects which may be surprising to the user. We describe some of those side-effects here.

Declaring Multiple Imports

In order to use elements from two FIX versions you must explicitly declare the imports at the top of the file. For our purposes we import FIX_4_2 and FIX_4_4. In this example we want to import the message OrderSingle from FIX_4_2 and message ExecutionReport from FIX_4_4. We do this with the code

import FIX_4_2
import FIX_4_4

internal state {
    assignable {
        Side : Side = Side.Buy;
    }
}

message OrderSingle {
    req Side
}

message ExecutionReport {
    req Side
}

In this example a warning will appear at on the import of the message ExecutionReport which says

This message is assumed to be from the FIX_4_2 but is also available from FIX_4_4; to avoid ambiguity please qualify using the library name for example "message FIX_4_2.ExecutionReport"

For our purposes we want to use the FIX_4_4 library so we modify the import of the library to message FIX_4_4.ExecutionReport { req Side } This configuration allows the import of fields such as PeggedPrice in message ExecutionReport:

message FIX_4_4.ExecutionReport {
    req Side
    req PeggedPrice
}

This would not be possible with FIX_4_2.ExecutionReportand would produce the error

Couldn't resolve reference to AbstractField 'PeggedPrice'.

as PeggedPrice does not exist in the declaration of ExecutionReport from FIX version 4.2.

Union of Record Fields and Enum Cases

One of the side effects of using multiple imports is that the cases available to enums are all of the cases available in both imports. For example the Sideenum which is the type of both Side fields in the OrderSingle and ExecutionReport messages, will have cases available from both FIX libraries. 4.2 and 4.4. If we introduce a receive block handler for the OrderSingle the language server completion elements for elements of type Side are:

Buy, Sell, BuyMinus, SellPlus, SellShort, SellShortExempt, Undisclosed, Cross, CrossShort, 
CrossShortExempt, AsDefined, Opposite, Subscribe, Redeem, Lend, Borrow

Those only from FIX version 4.2 are only

Buy, Sell, BuyMinus, SellPlus, SellShort, SellShortExempt, Undisclosed, Cross, CrossShort

which are the options were the only import to be import FIX_4_2

Inconsistency of Field Names

In an IPL model with one import, all fields with the same name must have the same tag and type; all fields with the same tag must have the same name. Any inconsistency here is marked as an error. When there are multiple imports there is an exception to this rule. We demonstrate this by way of an example. In our model we can import a field from FIX_4_2 and from FIX_4_4 which has the same tag but a different name:

import FIX_4_2
import FIX_4_4

internal state {
    assignable {
        Side : Side = Side.Buy;
    }
}

message OrderSingle {
    req Side
    req IDSource
}

message FIX_4_4.ExecutionReport {
    req Side
    req PeggedPrice
    req Instrument.SecurityIDSource
}

Both the field IDSource and field SecurityIDSource have tag "22" but this is allowed in this context. If we want to extend a new record with a new field of tag "22" the model will insist that it shares the name with any other field also referenced by tag in this model, and will choose the name according to the import names first. For example, in this context if we wish to make a new record and add a field with tag "22" we would do so in this model as follows:

declare record myRecord {
    IDSource "22" : IDSource
}

which is allowed. Attempting to write

declare record myRecord {
    SecurityIDSource "22" : SecurityIDSource
}

will result in the errors

Field SecurityIDSource has tag 22, but a field with the same tag but name IDSource already exists.

and

Type error, expected "IDSource" but was "SecurityIDSource"

In order to allow this we can change the order of imports:

import FIX_4_4
import FIX_4_2

and then the latter version becomes admissible.

When importing into the assignable section, both fields IDSource and SecurityIDSource are available and distinct.

Full Model – Imandra Analysis

Click on the image below for an interactive analysis of this model performed by imandra.

Model - IPL Code

//
//  Imandra Inc.
//  Copyright (c) 2024
//
//  Code for 'Multiple Imports Example'
//   
//  For further info see https://docs.imandra.ai
// 
// 
//

import FIX_4_2
import FIX_4_4

@title: "Multiple Imports Example"

messageFlows {
  NewOrderOnly {
    name "OrderOnly"
    description "Send OrderSingle Message"
    template[OrderSingle]
  } 
}

internal state {
  assignable {
    Side :  Side = Side.Buy;
  }
}

record myRecord {
  IDSource "22" : IDSource
}

message OrderSingle {
  req Side
  req IDSource
}

message FIX_4_4.ExecutionReport {
  req Side
  req PeggedPrice
  req Instrument.SecurityIDSource
}

Generated Documentation

Click here to view the generated documentation for this model.