Apama Capital Markets Foundation 10.7 | Capital Markets Foundation | Order Management | Risk firewall | Setting up risk firewall evaluation rules | Descriptions of default rule classes | About the ClientCreditLimitRiskFirewallRule
 
About the ClientCreditLimitRiskFirewallRule
The ClientCreditLimitRiskFirewallRule checks the total value of all orders that are being placed by a specific trader, or set of traders, to ensure that the total value does not breach the maximum credit limit that a trader is allowed.
Note:
The difference between the client credit limit rule class and the position limit rule class is that the client credit limit rule class acts on the cash position, which is the cumulative value of all orders, where as the position limit rule class acts on the cumulative quantity position.
When adding a client credit limit rule class instance, set either individual minimum and maximum limits, or a symmetric limit. For example, 100 would set a positive limit to +100 and a negative limit to -100. Setting both symmetric and asymmetric configuration parameters for the same limit (warning or objection) results in an error, and the rule class instance is not added.
This rule implementation relies on the order price being available when an order is placed against it, so that the rule can determine the order value. Therefore, this rule will not operate as expected for market orders being placed with a zero price value. In this case, the initial order may be allowed through the risk firewall. When the order receives a fill, then the risk firewall rule instance will be updated to reflect the current client credit position. At that point, any new orders, including market orders, will be rejected.
This risk firewall rule implementation is not designed for foreign exchange (FX) or mixed markets, as this implementation does not normalize the order values to a base currency value. It will use the value in the native currency for that order.
This risk firewall rule checks both the open and pending positions of matching orders.
When you use the client credit limit rule class (or the position limit rule class) there are callbacks that you must add. Specifically, you must add at least one of each type of callback to the order receiver that will handle orders approved by these rule classes:
*OrderReceiver.addAcceptedOrderCallback()
*OrderReceiver.addAcceptedAmendOrderCallback()
*OrderReceiver.addAcceptedCancelOrderCallback()
Each callback must route or enqueue the order event (com.apama.oms.NewOrder, AmendOrder, CancelOrder) to the context that contains the position tracker that the application is using. This is required for the rule class to operate in the expected way.
The client credit limit rule class uses the CMF position service to calculate the cumulative cash position being tracked. This requires the application to have created both an open position tracker and a pending position tracker (see Using default position trackers). You then pass the names of these position tracker instances into the rule class's create() action. This allows the rule class to track the positions of orders from other areas of your application.
The CMF's position service requires the order management (com.apama.oms) events to be sent (either routed or enqueued) to the position tracker instances that you created. This means that your application code must ensure that OMS events are sent to the position trackers being used after the orders have been approved by the risk firewall. Failure to do so may result in the position being calculated incorrectly, and subsequently the rule class may approve orders that would breach the defined limits.
CAUTION:
Where possible, the position trackers used should be in the same context as the risk firewall. This can help avoid a situation in which the client credit limit rule class approves orders that breach the defined limits. Such a situation might happen because the risk firewall can accept orders synchronously by means of callback actions, but the CMF position service is asynchronous. The position service listens for OMS events, and routes or enqueues position updates. Orders that are sent into the risk firewall should allow time for the correlator input queue to process the position update. The code sample at the end of this topic demonstrates what you must do to correctly implement the client credit limit rule class. Alternatively, you may implement a custom rule class implementation (see Implementing custom risk firewall rule classes) that can operate safely in a synchronous architecture.
The com.apama.firewall.rules.ClientCreditLimitRiskFirewallConsts object defines the constants for the configuration settings for the client credit limit rule class, as well as their default values. To configure a rule class instance, you should use these constants rather than specific values in order to ensure compatibility. The following table provides information about client credit limit rule class configuration parameters.
Constant Name of Input Parameter
Description
RULE_CLASS_NAME
The rule class name, which is "ClientCreditLimitRiskFirewallRule".
CLIENT_CREDIT_LIMIT_PARAMETER
Symmetric objection limits. This is the symmetric cash position up to which orders may accrue before the rule class rejects subsequent orders.
CLIENT_CREDIT_LIMIT_DEFAULT
Symmetric objection limits default, which is 0.0 by default.
CLIENT_CREDIT_WARNING_PARAMETER
Symmetric warning limits. This is the symmetric cash position up to which orders may accrue before the rule class issues a warning for subsequent orders.
CLIENT_CREDIT_WARNING_DEFAULT
Symmetric warning limits default, which is 0.0 by default.
MIN_CLIENT_CREDIT_LIMIT_PARAMETER
Minimum objection limit. This is the minimum cash position up to which orders may accrue before the rule class rejects subsequent orders.
MIN_CLIENT_CREDIT_LIMIT_DEFAULT
Minimum objection limit default value, which is 0.0.
MIN_CLIENT_CREDIT_WARNING_PARAMETER
Minimum warning limit. This is the minimum cash position up to which orders may accrue before the rule class issues a warning for subsequent orders.
MIN_CLIENT_CREDIT_WARNING_DEFAULT
Minimum warning limit default value, which is 0.0 by default.
MAX_CLIENT_CREDIT_LIMIT_PARAMETER
Maximum objection limit. This is the maximum cash position up to which orders may accrue before the rule class rejects subsequent orders.
MAX_CLIENT_CREDIT_LIMIT_DEFAULT
Maximum objection limit default value, which is 0.0 by default.
MAX_CLIENT_CREDIT_WARNING_PARAMETER
Maximum warning limit. This is the maximum cash position up to which orders may accrue before the rule class issues a warning for subsequent orders.
MIN_CLIENT_CREDIT_WARNING_DEFAULT
Maximum warning limit default value, which is 0.0 by default.
CHECK_CANCEL_PARAMETER
Indicates whether this risk firewall rule instance should apply to CancelOrder objects.
CHECK_CANCEL_DEFAULT
Default value for whether this risk firewall rule instance should apply to CancelOrder objects. By default, this is true, which means that cancel order requests are counted.
SLICE_POSITION_SERVICEID
The set of service IDs that the position service will use for this instance if it needs to be different from those provided for the instance slice. The format is a stringified sequence<string>. This must be set when running in legacy mode. You may want to check against the position of orders that have been approved by a risk firewall in legacy mode.
The following table provides information about client credit limit rule class state information parameters. The risk firewall uses these constants as part of the state returned in the com.apama.firewall.InstanceInfo object when you call the com.apama.firewall.RiskFirewall.getRulexxxInfo() set of actions.
Constant Name of Output Parameter
Description
CURRENT_OPEN_POSITION
Float value for the current open cash position for a rule class instance.
CURRENT_PENDING_MIN_POSITION
Minimum pending cash position for a rule instance.
CURRENT_PENDING_MAX_POSITION
Maximum pending cash position for a rule instance.
CURRENT_TOTAL_MIN_POSITION
Current total minimum (open + minimum pending) cash position for a rule class instance.
CURRENT_TOTAL_MAX_POSITION
Current total maximum (open + maximum pending) cash position for a rule class instance.
The following code provides an example of using the client credit limit rule class.
using com.apama.position.tracker.OpenPositionTrackerFactory;
using com.apama.position.tracker.PendingPostionTrackerFactory;
   
using com.apama.firewall.RiskFirewallFactory;
using com.apama.firewall.RiskFirewall;
using com.apama.firewall.RuleClassFactory;
using com.apama.firewall.rules.ClientCreditLimitRiskFirewallRule;
using com.apama.firewall.rules.ClientCreditLimitRiskFirewallRuleConsts;
 
using com.apama.utils.Params;
using com.apama.oms.NewOrder;
using com.apama.oms.AmendOrder;
using com.apama.oms.CancelOrder;
using com.apama.oms.UpdateOrder;
  
monitor ClientCreditLimitExample {
context mainContext := context.current();
integer trackersCreated := 0;
 
action onload() {
 
// Create an instance of the open position tracker in the main context.
(new OpenPositionTrackerFactory).create(
mainContext, "MyOpenPositionTracker", cbCreatedTracker );
// Create an instance of the pending position tracker in the main context.
(new PendingPositionTrackerFactory).create(
mainContext, "MyPendingPositionTracker", cbCreatedTracker );
   }
 
// This action is called after the position tracker instance
// has been created.
action cbCreatedTracker( boolean success, string msg ) {
log "Position Tracker has been created: "+success.toString()+" : "+msg;
 
trackersCreated := trackersCreated +1;
 
// After all trackers have been created, then start the test.
if( trackersCreated = 2 ) then {
startTest();
}
}
 
action startTest() {
// Create the risk firewall.
com.RiskFirewall rfw := (new RiskFirewallFactory).createCb(
mainContext, "MyFirewall", cbOnRiskFirewallCreated );
 
// Create and register the client credit limit rule class.
RuleClass ruleClass := (new ClientCreditLimitRiskFirewallRule).create(
mainContext, "MyOpenPositionTracker", "MyPendingPositionTracker" );
rfw.registerRuleClass( ruleClass );
 
// Add rule instances.
Params instanceConfig := new Params;
instanceConfig.addFloatParam(
ClientCreditLimitRiskFirewallRuleConsts.
CLIENT_CREDIT_LIMIT_PARAMETER, 500.0 );
instanceConfig.addFloatParam(
ClientCreditLimitRiskFirewallRuleConsts.
CLIENT_CREDIT_WARNING_PARAMETER,450.0 );
 
integer instanceId := rfw.addRuleInstance(
ruleClass.getRuleClassName(), instanceConfig );
 
// Add handlers for approved OMS events from the risk firewall.
integer refId1 := rfw.getOrderReceiver().addAcceptedOrderCallback(
cbOnApprovedNewOrders );
integer refId2 := rfw.getOrderReceiver().addAcceptedAmendCallback(
cbOnApprovedAmendOrders );
integer refId3 := rfw.getOrderReceiver().addAcceptedCancelCallback(
cbOnApprovedCancelOrders );
 
// Add a callback for obtaining OrderUpdate events from the risk firewall.
integer refId4 := rfw.getOrderSender().addOrderUpdateCallback(
cbOnOrderUpdates );
 
// The unlock will take effect immediately after the create() action.
rfw.unlock();
}
 
action cbOnRiskFirewallCreated( RiskFirewall rfw ) {
 
// Send a new order to the risk firewall.
rfw.getOrderSender().sendOrder( com.apama.oms.NewOrder(
"orderId_1","APMA.L", 9.0, "BUY", "LIMIT", 10,
"TargetService","","", "TargetMarket","", "TraderA",
new dictionary<string,string> ) );
}
 
// Set up a callback handler for NewOrder events approved by the
// risk firewall.
action cbOnApprovedNewOrders( NewOrder order ) {
// Send the NewOrder event to the context that the position trackers
// were created in.
route order;
 
// The application can now perform any other actions
// on this NewOrder event.
...
}
 
// Set up a callback handler for AmendOrder events approved by the
// risk firewall.
action cbOnApprovedAmendOrders( AmendOrder amend ) {
// Send the AmendOrder event to the context that the position trackers
// were created in.
route amend;
 
// The application can now perform any other actions
// on this AmendOrder event.
...
}
 
// Set up a callback handler for CancelOrder events approved by the
// risk firewall.
action cbOnApprovedCancelOrders( CancelOrder cancel ) {
// Send the CancelOrder event to the context that the position trackers
// were created in.
route cancel;
 
// The application can now perform any other actions
// on this CancelOrder event.
...
}
 
// This action will be called for any updates to the
// orders the risk firewall is handling.
action cbOnOrderUpdates( OrderUpdate update ) {
// Send the OrderUpdate event to the context that the position trackers
// were created in
route update;
 
// The application can now perform any other actions
// on this OrderUpdate event.
...
}
}