Appendix 4: AMDL Annotations

This section provides a complete list of annotations in AMDL, each of which is accompanied by a brief description.

@alert

This annotation must be applied to an AMDL rule to generate an alert when the rule triggers. If this is not applied to a rule, an alert is not generated and therefore the outcome is not be visible on the Incident List of the Fraud Transaction Monitoring System.

Copy
@alert
rules.dummyRule: 1 == 1

@array

  • @array(<duration>)

  • @array(<length>)

  • @array(duration=<duration>, size=<length>)

This modifies the type of a state expression such that it captures an array, which in the context of AMDL refers to an ordered collection of objects. The size of an array must be limited by specifying a duration (in which case elements older than the specified duration will expire and be removed), or a fixed length (in which case the oldest element will be removed each time a new element is added, once the array reaches that length), or both (using named arguments, 'duration' and 'size').

If duration and length limits are both specified, the oldest element is removed if the array reaches its size limit when a new element is added. However, elements older than the duration are also be removed. A default size limit of 1000 elements is applied to all AMDL collections, including arrays. While this can be overridden by specifying a larger length limit, it is not recommended to do so, as this limit prevents performance issues due to large amounts of state data stored in a single collection.

Copy
@array(30d)
state.lastMonthsTransactions: event.amount.baseValue

@comment

  • @comment(<comment>)

This annotation has no functionality, but can be used to add comments to AMDL expressions.

Copy
@comment
(
"place your comment here"
)
rules.dummyRule 1 == 1

@description

  • @description(<description>)

This annotation provides a tool tip that appears when users hover over the Triggered Rules column in the Incident List.

Copy
@description("place your description here")
rules.dummyRule 1 == 1

@defaultValue

  • @defaultValue(<defaultValue>)

Any single-value state or global expression can have a default value applied. However, the default value is referenced but does not yet exist using this annotation. If the state already exists, the default value is not applied.

This annotation cannot be used with expressions that store collections of values, such as arrays, set or histograms.

Copy
@defaultValue
(
0)
state.myCount: event.amount.baseValue

@eventType

  • @eventType(<eventType>)

An AMDL Business Rules expression accompanied by this annotation is only evaluated for events of the type specified within parentheses. Multiple such annotations can be used to allow evaluation on more than one defined events. If no @eventType annotation is provided for a Business Rules expression, it is evaluated for all event types by default.

Copy
@eventType(registration)
rules.dummyRule: 1 == 1

@firstValue

  • @eventType(<eventType>)

Any state expression with this annotation is updated if it does not already exist. As such, it effectively captures the first value to which it is evaluated.

Copy
@firstValue
state.firstSeen: event.eventTime

@histogram

  • @histogram(historyLength=<duration>, bucketSize=<bin width>)

  • @histogram(historyLength=<duration>, bucketSize=<bin width>, timeField=<time field>)

This modifies the type of a state expression to a histogram, which in AMDL refers to a collection of accumulated values, bucketed by time. The @histogram annotation can take an optional argument, timeField, which allows you to define a non-default time field to use.

The following is an example of a global histogram that stores transactions over the last week as follows:

Copy
@histogram
(historyLength=7d, bucketSize=1d)
globals.txAmounts: event.amount.baseValue

For more information, see Using Histograms.

@initialContents

  • @initialContents(<initialContents>)

Any state expression defined as an array or set can have initial contents — elements of the collection which are defined prior to the state expression being updated for the first time. If the state is referenced but does not exist yet, or when the state is updated for the first time, these values are assigned to the collection before the state expression is evaluated or updated.

Copy
@initialContents([0,0,0,0,0])
@array(5)
state.setTest: event.amount.baseValue

@mapOptions

  • @mapOptions(keyDuration=<duration>, keySize=<size>)

When using a state or global expression to define a dynamic map, use this optional annotation to set a limit on the number of keys in the map.

Use the keyDuration argument to set a duration limit. The duration argument ensures that each time the map is updated, keys that were last updated before the specified duration are removed from the map.

Use the keySize argument to specify a fixed size limit. This ensures that once the number of keys stored in the map reaches this size, each time a new key is added, the key that was last updated longest ago is removed. If you use both arguments, keys are removed from the map according to whichever limit is reached first.

Copy
@eventType ("transaction")
@mapOptions (keyDuration=14d, keySize=100)
state.previousCurrencyAmount[ event.amount.currency ]:
event.amount.baseValue

A default size limit of 1000 keys is applied to all maps. While this can be overridden by specifying a larger size limit, it is not recommended to do so, as this can create performance issues due to large amounts of state data stored in a single map. This is particularly relevant for nested maps that store a collection of values with each key. For more information about maps, see Using Lookup Tables.

@output

  • @output(<namespace>)

  • @output(mode=ruleoutput)

This annotation modifies a var expression so that it assigns a tag with the value of that expression for each event for which it is calculated, or outputs the results in the Fraud Transaction Monitoring System output. If outputting as a tag, you can provide an optional namespace argument. If omitted, the tag generated will use the name of the var expression as its namespace.

This annotation modifies a var expression so that it assigns a tag with the value of that expression for each calculated event, or outputs the results in the fraud system output. If outputting as a tag, you can provide an optional namespace argument. If omitted, the generated tag uses the name of the var expression as its namespace.

Copy
@output("Twice the transaction amount")
var.twiceAmount: 2* event.amount.baseValue

@rollingAverage

  • @rollingAverage(<duration>)

This modifies the type of a state expression to a rolling average. The rolling average provides the average of all values it is updated with, and is weighted so that the weight of each historical value decays with time.

Copy
@rollingAverage(7d)
globals.txAmounts: event.amount.baseValue

The rolling average is implemented internally as an exponentially decaying total and count value with a time period defined by the duration argument of the annotation. This means that expressions of this type do not require substantial storage space and therefore this is generally safe to use in high-throughput states such as globals.

The following equation shows the value of a rolling average for the ith update of the expression (which happens at time ti) is calculated as the ratio of the exponentially decayed totalT, and countC :

Both the exponentially decayed total and the exponentially decayed count for the rolling average are calculated from equations consisting of various coefficients. The exponentially decayed total is calculated as:

The exponentially decayed count is calculated as:

T is the duration specified as an argument to the annotation, xi is the value the update expression evaluates to (for example the transaction amount in the example above) and Ti-1 signifies the time of the previous update of this expression.

@score

  • @score(<score>)

This annotation enables rules to contribute to the overall risk score of a particular event or entity combination. A rule modified with this annotation adds the score specified in the argument to the risk score output by the 'businessrules' model. This model outputs the total of the scores assigned by all triggered rules.

Copy
@score(1.5)
rules.dummyRule: 1 == 1

@set

  • @set(<duration>)

  • @set(<length>)

  • @set(duration=<duration>, size=<length>)

This annotation modifies the type of a state expression such that it captures a set, which in AMDL is an unordered collection of unique objects. Sets must be limited by specifying either a duration (in which case elements older than the specified duration will expire and be removed), or a fixed length (in which case the oldest element will be removed each time a new unique element is added, once the set reaches that length).

If a value which already exists is added to the set, the expiration timer upon that element will be reset. If duration and length limits are both specified, the oldest element will be removed if the set reaches its size limit when a new element is added, but elements older than the duration will also be removed. A default size limit of 1000 elements is applied to all AMDL collections, including sets.

Copy
@set(30d)
state.methodIdsLastMonth: event.methodId

@suppressAlert

This annotation modifies a rule where triggering for a particular event or entity combination, suppresses all alerts for that event or entity combination. This annotation is implemented as part of the implicit rules aggregator step, so applies to alerts generated by rules, models (risk thresholds), and aggregators.

Copy
@suppressAlert
rules.noAlertsOnWhitelist: lists.whitelist ~# event.customerId

@suppressTag

  • @suppressTag(<namespace>="<tagValue>")

This annotation modifies a rule where triggering for a particular event or entity combination, suppresses a particular tag value (specified in the argument to this annotation). The namespace is optional. If no namespace is given, this annotation suppresses the tag with the default namespace and the specified value. This annotation is implemented as part of the implicit rules aggregator step, so applies to tags assigned by rules, models (risk thresholds), and aggregators.

Copy
@suppressTag
(action="deny")
rules.noDeclinesOnWhiteList: lists.whitelist ~# event.customerId

@tag

  • @tag(<namespace>="<tagValue>")

This annotation is only applicable to rule expressions. If a rule triggers, the tag is appended to the response. The namespace is an optional argument. If no namespace is given (@tag("<tagValue>")), then this annotation is assigned to the default namespace (_tag). Multiple tag annotations can form part of any AMDL rule.

Copy
@tag(action="deny")
rules.dummyRule: 1 == 1

For more information on the different tags, see Appendix 6: Tags.