public static void Add(Restriction restriction, Position position, params object[] argument) { RemoteAssembly remoteAssembly = CommandBatch.Assemblies.Add("Service.Core"); RemoteType remoteType = remoteAssembly.Types.Add("Shadows.WebService.Core.Violation"); RemoteMethod remoteMethod = remoteType.Methods.Add("Insert"); remoteMethod.Parameters.Add("restrictionId", restriction.RestrictionId); remoteMethod.Parameters.Add("accountId", position.Account.AccountId); remoteMethod.Parameters.Add("securityId", position.Security.SecurityId); remoteMethod.Parameters.Add("positionTypeCode", (int)position.PositionType); remoteMethod.Parameters.Add("description", String.Format(restriction.Description, argument)); }
/// <summary> /// Installs an event driven industry concentration compliance check. /// </summary> static TelecomConcentration() { // This is a list of all the accounts targeted by this compliance check. TelecomConcentration.betaAccountList = new BetaAccountList(); // This is the preset concentration limit. TelecomConcentration.sectorLimit = 0.1M; // Find the telecom sector based on the S&P GICS external codes. TelecomConcentration.telecomServices = new Sector("50"); // Open up a restriction for the industry concentration rule. The severity level of these errors is high and an // officer approval is needed to trade any positions. TelecomConcentration.restriction = Restriction.Find("TELECOMSECTOR"); if (TelecomConcentration.restriction == null) { TelecomConcentration.restriction = new Restriction("TELECOMSECTOR", Severity.High, Approval.Officer, "{0} in account {1} exceeds {2:#0%} in {3}."); } // Cycle through each predefined account and synchronize the violations against the current state of the data model. // The method 'AccountHandler' will check the given account for an exceesive concentration in the Telecommunications // Sector. foreach (Account account in TelecomConcentration.betaAccountList) { ValidateAccount(account); } // Flush the command buffer. CommandBatch.Flush(); // This list collects the positions that have been changed by the incoming events. TelecomConcentration.updateAccountList = new AccountList(); // This compliance check is event driven. When an event -- such as adding or deleting an order -- changes the state of // the data model, these tests will be called to insure that the new state doesn't violate this compliance rule. In // the case of a simple list rule, the new position will be tested to see if adding or deleting a position results in a // violation. These statements install the event handlers for tax lots, proposed orders, orders and allocations. For // example, the method 'TaxLotHandler' will be called when the tax lot table changes. MarketData.BeginMerge += new EventHandler(BeginMerge); TaxLot.Changed += new TaxLotEvent(TaxLotHandler); ProposedOrder.Changed += new ProposedOrderEvent(ProposedOrderHandler); Order.Changed += new OrderEvent(OrderHandler); Allocation.Changed += new AllocationEvent(AllocationHandler); MarketData.EndMerge += new EventHandler(EndMerge); }
public static Restriction Find(string restrictionId) { Restriction restriction = null; try { // Lock the tables. Debug.Assert(!ClientMarketData.AreLocksHeld); ClientMarketData.ConfigurationLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.RestrictionLock.AcquireReaderLock(CommonTimeout.LockWait); int internalRestrictionId = FindKey("DEFAULT", restrictionId); if (internalRestrictionId != Identifier.NotFound) { ClientMarketData.RestrictionRow restrictionRow = ClientMarketData.Restriction.FindByRestrictionId(internalRestrictionId); if (restrictionRow == null) { throw new Exception(string.Format("Restriction {0} can'b be found", internalRestrictionId)); } restriction = new Restriction(restrictionRow); } } finally { // Release the table locks. if (ClientMarketData.ConfigurationLock.IsReaderLockHeld) { ClientMarketData.ConfigurationLock.ReleaseReaderLock(); } if (ClientMarketData.RestrictionLock.IsReaderLockHeld) { ClientMarketData.RestrictionLock.ReleaseReaderLock(); } Debug.Assert(!ClientMarketData.AreLocksHeld); } return(restriction); }
/// <summary> /// Install an event driven compliance check and initialize the violations table. /// </summary> static AlphaListRule() { // This will create a table of positions for every combination of a restricted securities in a restricted account. // This is just one example of how a set of restricted positions could be created. AlphaListRule.alphaPositionTable = new PositionTable(new AlphaAccountList(), new AlphaSecurityList()); AlphaListRule.updatePositionTable = new PositionTable(); // This a simple "Restricted Security" compliance check. If a position exists or is created on the predefined account // and security combination, then a 'Violation' record will be created. Conversely, if those conditions are removed, // the corresponding violation will be deleted. The first parameter to opening up a 'Restriction' is the user-defined // name, which must be unique for this rule. The restriction can specify a severity level and how many overrides are // required to allow it to trade. Also, a message with replacable parameters can be specified here. When a violation // is created, this message and the optional data items are combined to create a specific message for the violation. In // this example, the ticker symbol and account name will be filled when the violation is created. AlphaListRule.restriction = Restriction.Find("ALPHALIST"); if (AlphaListRule.restriction == null) { AlphaListRule.restriction = new Restriction("ALPHALIST", Severity.High, Approval.Officer, "Security '{0}' is restricted from account {1}."); } // The violations need to be synchronized with the current state of the data model when this compliance check is first // installed . That is, since the programming model is event driven, the state of the violations has to be initialized // for the incremental rule checking to work. This step will remove any violations that are no longer valid. foreach (Violation violation in restriction.GetViolations()) { if (violation.Position.GetQuantity() == 0.0M) { violation.Remove(); } } // This will complete the task of synchronizing the data model for the compliance rule. If a non-zero position is // found in the list of restricted securities and accounts, a violation on that position will be generated. foreach (Position position in AlphaListRule.alphaPositionTable) { // Create a position object based on the account, security and long or short position type. Any quantity found for // that position will trigger a violation. Note that if a violation already exists for this restriction and // position combination, the description of the violation will be overwritten, but the record will be otherwise // unchanged. if (position.GetQuantity() != 0.0M) { Violation violation = Violation.Find(restriction, position); if (violation == null) { Violation.Add(restriction, position, position.Security.Symbol, position.Account.Name); } } } // Flush the command buffer. CommandBatch.Flush(); // This compliance check is event driven. When an event -- such as adding or deleting an order -- changes the state of // the data model, these tests will be called to insure that the new state doesn't violate this compliance rule. In // the case of a simple list rule, the new position will be tested to see if adding or deleting a position results in a // violation. These statements install the event handlers for tax lots, proposed orders, orders and allocations. For // example, the method 'TaxLotHandler' will be called when the tax lot table changes. MarketData.BeginMerge += new EventHandler(BeginMerge); TaxLot.Changed += new TaxLotEvent(TaxLotHandler); ProposedOrder.Changed += new ProposedOrderEvent(ProposedOrderHandler); Order.Changed += new OrderEvent(OrderHandler); Allocation.Changed += new AllocationEvent(AllocationHandler); MarketData.EndMerge += new EventHandler(EndMerge); }