/// <summary> /// Starts a simulated price feed. /// </summary> /// <param name="transaction">Used to commit or reject one or more operations as a unit.</param> /// <param name="remoteMethod">A metadata description of the method to be executed.</param> public static void Start(Transaction transaction, RemoteMethod remoteMethod) { // This keeps track of the number of threads running. Price.simulatorCounter++; // This will be the name and primary identifier of the market simulation thread, unless an explicit name is provided // with the method parameters. string defaultThreadName = string.Format("Market Price {0}", simulatorCounter); // Extract the parameters from the batch. decimal tickerRate = remoteMethod.Parameters.GetRequiredDecimal("tickerRate", Price.DefaultTickerRate); string name = remoteMethod.Parameters.GetRequiredString("name", defaultThreadName); // This governs how fast the ticks are generated. Note that logic will prevent time between ticks from being set to // zero. It's important that the timer is never set to zero: with no time to rest between ticks, it's difficult for // any new tasks to get connected. Price.Timer = Convert.ToInt32(1000.0M / tickerRate); // Start the thread that will simulate the market conditions. Note that the Hash table allows the thread to be // referenced by name on any later method invokations. marketThreadTable[name] = new Thread(new ThreadStart(MarketThread)); Thread thread = (Thread)marketThreadTable[name]; thread.Name = name; thread.Start(); }
/// <summary>Archives a Order record using Metadata Parameters.</summary> /// <param name="transaction">Commits or rejects a set of commands as a unit</param> /// <param name="remoteMethod">Contains the parameters and exceptions for this command.</param> public static void Archive(Transaction transaction, RemoteMethod remoteMethod) { try { // Extract the parameters from the command batch. int orderId = remoteMethod.Parameters.GetRequiredInt32("orderId"); long rowVersion = remoteMethod.Parameters.GetRequiredInt64("rowVersion"); // Make sure the parameters were parsed correctly before calling the internal method. This will prevent the method // from being called with bad data, but provides for error checking on all the parameters. if ((remoteMethod.HasExceptions == false)) { // Call the internal method to complete the operation. Order.Archive(transaction, orderId, rowVersion); } } catch (SqlException sqlException) { // Every exception from the SQL server call is packed into the 'RemoteMethod' structure and returned to the caller. for (IEnumerator iEnumerator = sqlException.Errors.GetEnumerator(); iEnumerator.MoveNext(); remoteMethod.Exceptions.Add(((SqlError)(iEnumerator.Current)).Message)) { } } catch (Exception exception) { // This will pass the general exception back to the caller. remoteMethod.Exceptions.Add(exception); } }
/// <summary> /// Sets the operating parameters of the simulator. /// </summary> /// <param name="transaction">Used to commit or reject one or more operations as a unit.</param> /// <param name="remoteMethod">A metadata description of the method to be executed.</param> public static void SetHeuristics(Transaction transaction, RemoteMethod remoteMethod) { // Extract the method parameters. decimal tickerRate = remoteMethod.Parameters.GetRequiredDecimal("tickerRate", Price.DefaultTickerRate); // Set the time between simulated ticks. This governs how many ticks will be generated per second. Price.Timer = Convert.ToInt32(1000.0M / tickerRate); }
/// <summary> /// Creates a temporary copy of a model portfolio. /// </summary> /// <param name="modelRow">The original model record.</param> /// <returns>A batch of commands that will create a copy of the original model.</returns> private static ModelBatch CopyModel(ClientMarketData.ModelRow modelRow) { // Create the batch and fill it in with the assembly and type needed for this function. ModelBatch modelBatch = new ModelBatch(); RemoteAssembly remoteAssembly = modelBatch.Assemblies.Add("Service.Core"); RemoteType remoteType = remoteAssembly.Types.Add("Shadows.WebService.Core.Model"); // This method will insert a copy of the original model's header. RemoteMethod insertModel = remoteType.Methods.Add("Insert"); insertModel.Parameters.Add("modelId", DataType.Int, Direction.ReturnValue); insertModel.Parameters.Add("rowVersion", DataType.Long, Direction.Output); insertModel.Parameters.Add("objectTypeCode", modelRow.ObjectRow.ObjectTypeCode); insertModel.Parameters.Add("name", String.Format("Copy of {0}", modelRow.ObjectRow.Name)); insertModel.Parameters.Add("schemeId", modelRow.SchemeId); insertModel.Parameters.Add("algorithmId", modelRow.AlgorithmId); insertModel.Parameters.Add("temporary", true); insertModel.Parameters.Add("description", modelRow.ObjectRow.Description); // For a sector model, copy each of the sector level targets into the destination model. if (modelRow.ModelTypeCode == ModelType.Sector) { // The object Type for this operation. RemoteType sectorTargetType = remoteAssembly.Types.Add("Shadows.WebService.Core.SectorTarget"); // Add the position level target to the model. foreach (ClientMarketData.SectorTargetRow sectorTargetRow in modelRow.GetSectorTargetRows()) { RemoteMethod insertSector = sectorTargetType.Methods.Add("Insert"); insertSector.Parameters.Add("modelId", insertModel.Parameters["modelId"]); insertSector.Parameters.Add("sectorId", sectorTargetRow.SectorId); insertSector.Parameters.Add("percent", sectorTargetRow.Percent); } } // For a position model, copy each of the position level targets into the destination model. if (modelRow.ModelTypeCode == ModelType.Security) { // The object Type for this operation. RemoteType positionTargetType = remoteAssembly.Types.Add("Shadows.WebService.Core.PositionTarget"); // Add the position level target to the model. foreach (ClientMarketData.PositionTargetRow positionTargetRow in modelRow.GetPositionTargetRows()) { RemoteMethod insertSecurity = positionTargetType.Methods.Add("Insert"); insertSecurity.Parameters.Add("modelId", insertModel.Parameters["modelId"]); insertSecurity.Parameters.Add("securityId", positionTargetRow.SecurityId); insertSecurity.Parameters.Add("positionTypeCode", positionTargetRow.PositionTypeCode); insertSecurity.Parameters.Add("percent", positionTargetRow.Percent); } } // Save the reference to the 'modelId' return parameter. modelBatch.ModelIdParameter = insertModel.Parameters["modelId"]; // This batch will create a copy of the original model. return(modelBatch); }
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> /// Starts a simulated price feed. /// </summary> /// <param name="transaction">Used to commit or reject one or more operations as a unit.</param> /// <param name="remoteMethod">A metadata description of the method to be executed.</param> public static void Start(Transaction transaction, RemoteMethod remoteMethod) { // Extract the parameters from the batch. string name = remoteMethod.Parameters.GetRequiredString("name"); // The 'name' used to start this thread is really a broker symbol. Use the tables to find a broker symbol that matches // the name. This will become the broker identifier that this simulation thread responds to. object brokerId = null; try { // Lock the tables Debug.Assert(!ServerMarketData.AreLocksHeld); ServerMarketData.BrokerLock.AcquireReaderLock(Timeout.Infinite); // Search, the hard way, for a symbol that matches the simulator name. foreach (ServerMarketData.BrokerRow brokerRow in ServerMarketData.Broker) { if (brokerRow.Symbol == name) { brokerId = brokerRow.BrokerId; } } } finally { // Release the broker table. if (ServerMarketData.BrokerLock.IsReaderLockHeld) { ServerMarketData.BrokerLock.ReleaseReaderLock(); } } // If the broker identifier was found, then start the simulation threads to service all electronic placements that are // destined for that broker. if (brokerId != null) { // This list is used to filter out brokers that aren't recognized by this simulator. Broker.brokerList.Add(brokerId); // This thread will remove placements from the queue and create orders in the local order book. Thread placementThread = new Thread(new ThreadStart(PlacementHandler)); placementThread.Start(); // Start the thread to handle the random execution of orders in the local order book. ThreadArgument threadArgument = new ThreadArgument(new ThreadHandler(ExecutionThread), "Execution Thread", brokerId); Thread executionThread = new Thread(new ThreadStart(threadArgument.StartThread)); executionThread.Start(); } }
private void Register(Int16 methodHash, RemoteMethod remoteMethod) { if (!_methods.ContainsKey(methodHash)) { _methods.Add(methodHash, remoteMethod); } else { var hashConflict = _methods[methodHash].Method.Name; var errorMsg = remoteMethod.Method.Name + " shares hash with " + hashConflict + ". Rename one before registering callback."; throw new InvalidOperationException(errorMsg); } }
/// <summary>Inserts a Order record using Metadata Parameters.</summary> /// <param name="transaction">Commits or rejects a set of commands as a unit</param> /// <param name="remoteMethod">Contains the parameters and exceptions for this command.</param> public static void Insert(Transaction transaction, RemoteMethod remoteMethod) { try { // Accessor for the Order Table. ServerMarketData.OrderDataTable orderTable = ServerMarketData.Order; // Extract the parameters from the command batch. string configurationId = remoteMethod.Parameters.GetRequiredString("configurationId", "DEFAULT"); string externalAccountId = remoteMethod.Parameters.GetRequiredString("accountId"); string externalSecurityId = remoteMethod.Parameters.GetRequiredString("securityId"); string externalSettlementId = remoteMethod.Parameters.GetRequiredString("settlementId"); string externalTransactionTypeCode = remoteMethod.Parameters.GetRequiredString("transactionTypeCode"); string externalTimeInForceCode = remoteMethod.Parameters.GetRequiredString("timeInForceCode"); string externalOrderTypeCode = remoteMethod.Parameters.GetRequiredString("orderTypeCode"); System.Decimal quantity = remoteMethod.Parameters.GetRequiredDecimal("quantity"); object price1 = remoteMethod.Parameters.GetOptionalDecimal("price1"); object price2 = remoteMethod.Parameters.GetOptionalDecimal("price2"); // Make sure the parameters were parsed correctly before calling the internal method. This will prevent the method // from being called with bad data, but provides for error checking on all the parameters. if ((remoteMethod.HasExceptions == false)) { // The row versioning is largely disabled for external operations. The value is returned to the caller in the // event it's needed for operations within the batch. long rowVersion = long.MinValue; // Resolve External Identifiers int accountId = External.Account.FindRequiredKey(configurationId, "accountId", externalAccountId); int securityId = External.Security.FindRequiredKey(configurationId, "securityId", externalSecurityId); int settlementId = External.Security.FindRequiredKey(configurationId, "settlementId", externalSettlementId); int transactionTypeCode = External.TransactionType.FindRequiredKey(configurationId, "transactionTypeCode", externalTransactionTypeCode); int timeInForceCode = External.TimeInForce.FindRequiredKey(configurationId, "timeInForceCode", externalTimeInForceCode); int orderTypeCode = External.OrderType.FindRequiredKey(configurationId, "orderTypeCode", externalOrderTypeCode); // Call the internal method to complete the operation. Shadows.WebService.Trading.Order.Insert(transaction, null, null, accountId, securityId, settlementId, null, transactionTypeCode, timeInForceCode, orderTypeCode, null, ref rowVersion, null, quantity, price1, price2, null); // Return values. remoteMethod.Parameters.ReturnValue("rowVersion", rowVersion); } } catch (SqlException sqlException) { // Every exception from the SQL server call is packed into the 'RemoteMethod' structure and returned to the caller. for (IEnumerator iEnumerator = sqlException.Errors.GetEnumerator(); iEnumerator.MoveNext(); remoteMethod.Exceptions.Add(((SqlError)(iEnumerator.Current)).Message)) { } } catch (Exception exception) { // This will pass the general exception back to the caller. remoteMethod.Exceptions.Add(exception); } }
/// <summary> /// Creates a block order. /// </summary> /// <param name="configurationId">Defines which external fields are used to identify an object.</param> /// <param name="blotterId">The destination blotter for the trade.</param> /// <param name="securityId">The security.</param> /// <param name="transactionType">The type of transaction.</param> public BlockOrder(Blotter blotter, Security security, TransactionType transactionType) { // Create a block order on the server. RemoteBatch remoteBatch = new RemoteBatch(); RemoteAssembly remoteAssembly = remoteBatch.Assemblies.Add("Service.Trading"); RemoteType remoteType = remoteAssembly.Types.Add("Shadows.WebService.Trading.BlockOrder"); RemoteMethod remoteMethod = remoteType.Methods.Add("Insert"); remoteMethod.Parameters.Add("blockOrderId", DataType.Int, Direction.ReturnValue); remoteMethod.Parameters.Add("blotterId", blotter.BlotterId); remoteMethod.Parameters.Add("securityId", security.SecurityId); remoteMethod.Parameters.Add("settlementId", security.SettlementId); remoteMethod.Parameters.Add("transactionTypeCode", (int)transactionType); ClientMarketData.Execute(remoteBatch); // Now that the block order is created, construct the in-memory version of the record. int blockOrderId = (int)remoteMethod.Parameters["blockOrderId"].Value; try { // Lock the tables. Debug.Assert(!ClientMarketData.AreLocksHeld); ClientMarketData.BlockOrderLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.ObjectLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.SecurityLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.BlockOrderRow blockOrderRow = ClientMarketData.BlockOrder.FindByBlockOrderId(blockOrderId); if (blockOrderRow == null) throw new Exception(String.Format("BlockOrder {0} doesn't exist", blockOrderId)); this.blockOrderId = blockOrderRow.BlockOrderId; this.security = Security.Make(blockOrderRow.SecurityRowByFKSecurityBlockOrderSecurityId.SecurityId); this.settlement = Security.Make(blockOrderRow.SecurityRowByFKSecurityBlockOrderSettlementId.SecurityId); this.transactionType = (TransactionType)blockOrderRow.TransactionTypeCode; } finally { // Release the table locks. if (ClientMarketData.BlockOrderLock.IsReaderLockHeld) ClientMarketData.BlockOrderLock.ReleaseReaderLock(); if (ClientMarketData.ObjectLock.IsReaderLockHeld) ClientMarketData.ObjectLock.ReleaseReaderLock(); if (ClientMarketData.SecurityLock.IsReaderLockHeld) ClientMarketData.SecurityLock.ReleaseReaderLock(); Debug.Assert(!ClientMarketData.AreLocksHeld); } }
public RpcClient(ISerializer serializer, TimeSpan rpcTimeout, IThreadDispatcher threadDispatcher) { using (EneterTrace.Entering()) { if (serializer == null) { string anError = "Input parameter serializer is null."; EneterTrace.Error(anError); throw new ArgumentNullException(anError); } mySerializer = serializer; myRpcTimeout = rpcTimeout; #if !NETSTANDARD ServiceInterfaceChecker.CheckForClient <TServiceInterface>(); // Dynamically implement and instantiate the given interface as the proxy. Proxy = ProxyProvider.CreateInstance <TServiceInterface>(CallMethod, SubscribeEvent, UnsubscribeEvent); #endif // Store remote methods. foreach (MethodInfo aMethodInfo in typeof(TServiceInterface).GetMethods()) { Type aReturnType = aMethodInfo.ReturnType; Type[] anArgTypes = aMethodInfo.GetParameters().Select(x => x.ParameterType).ToArray(); RemoteMethod aRemoteMethod = new RemoteMethod(aReturnType, anArgTypes); myRemoteMethods[aMethodInfo.Name] = aRemoteMethod; } // Store remote events. foreach (EventInfo anEventInfo in typeof(TServiceInterface).GetEvents()) { if (anEventInfo.EventHandlerType.IsGenericType) { RemoteEvent aRemoteEvent = new RemoteEvent(anEventInfo.EventHandlerType.GetGenericArguments()[0]); myRemoteEvents[anEventInfo.Name] = aRemoteEvent; } else { RemoteEvent aRemoteEvent = new RemoteEvent(typeof(EventArgs)); myRemoteEvents[anEventInfo.Name] = aRemoteEvent; } } myThreadDispatcher = threadDispatcher; } }
/// <summary> /// Executes a block order. /// </summary> /// <param name="configurationId">Defines which external fields are used to identify an object.</param> /// <param name="brokerId">The destination broker for the order.</param> /// <param name="tif">Specifies a time limit on the order.</param> /// <param name="quantity">The number of units to be traded.</param> /// <param name="pricedAt">Specifies how the order is to be priced.</param> /// <param name="limitPrice">A limit price for the order.</param> public void Execute(Broker broker, TIF tif, decimal quantity, PricedAt pricedAt, decimal limitPrice) { RemoteBatch remoteBatch = new RemoteBatch(); RemoteAssembly remoteAssembly = remoteBatch.Assemblies.Add("Service.Trading"); RemoteType remoteType = remoteAssembly.Types.Add("Shadows.WebService.Trading.BlockOrder"); RemoteMethod remoteMethod = remoteType.Methods.Add("Execute"); remoteMethod.Parameters.Add("blockOrderId", this.blockOrderId); remoteMethod.Parameters.Add("brokerId", broker.BrokerId); remoteMethod.Parameters.Add("timeInForceCode", (int)tif); remoteMethod.Parameters.Add("quantity", quantity); remoteMethod.Parameters.Add("orderTypeCode", (int)pricedAt); remoteMethod.Parameters.Add("price1", limitPrice); ClientMarketData.Execute(remoteBatch); }
public Restriction(string restrictionId, Severity severity, Approval approval, string description) { RemoteBatch remoteBatch = new RemoteBatch(); RemoteAssembly remoteAssembly = remoteBatch.Assemblies.Add("Service.Core"); RemoteType remoteType = remoteAssembly.Types.Add("Shadows.WebService.Core.Restriction"); RemoteMethod remoteMethod = remoteType.Methods.Add("Insert"); remoteMethod.Parameters.Add("internalRestrictionId", DataType.Int, Direction.ReturnValue); remoteMethod.Parameters.Add("severity", (int)severity); remoteMethod.Parameters.Add("approval", (int)approval); remoteMethod.Parameters.Add("description", description); remoteMethod.Parameters.Add("userId0", restrictionId); ClientMarketData.Send(remoteBatch); Initialize((int)remoteMethod.Parameters["internalRestrictionId"].Value); }
/// <summary>Inserts a Order record using Metadata Parameters.</summary> /// <param name="transaction">Commits or rejects a set of commands as a unit.</param> /// <param name="remoteMethod">Contains the metadata parameters and exceptions for this command.</param> public static void Insert(Transaction transaction, RemoteMethod remoteMethod) { try { // Extract the parameters from the command batch. object blockOrderId = remoteMethod.Parameters.GetOptionalInt32("blockOrderId"); object blotterId = remoteMethod.Parameters.GetOptionalInt32("blotterId"); int accountId = remoteMethod.Parameters.GetRequiredInt32("accountId"); int securityId = remoteMethod.Parameters.GetRequiredInt32("securityId"); int settlementId = remoteMethod.Parameters.GetRequiredInt32("settlementId"); object brokerId = remoteMethod.Parameters.GetOptionalInt32("brokerId"); int transactionTypeCode = remoteMethod.Parameters.GetRequiredInt32("transactionTypeCode"); int timeInForceCode = remoteMethod.Parameters.GetRequiredInt32("timeInForceCode"); int orderTypeCode = remoteMethod.Parameters.GetRequiredInt32("orderTypeCode"); object conditionCode = remoteMethod.Parameters.GetOptionalInt32("conditionCode"); object isAgency = remoteMethod.Parameters.GetOptionalBoolean("isAgency"); System.Decimal quantity = remoteMethod.Parameters.GetRequiredDecimal("quantity"); object price1 = remoteMethod.Parameters.GetOptionalDecimal("price1"); object price2 = remoteMethod.Parameters.GetOptionalDecimal("price2"); object note = remoteMethod.Parameters.GetOptionalString("note"); // Make sure the parameters were parsed correctly before calling the internal method. This will prevent the method // from being called with bad data, but provides for error checking on all the parameters. if ((remoteMethod.HasExceptions == false)) { // The rowVersion is passed back to the caller in the event it's needed for additional commands in the batch. long rowVersion = long.MinValue; // Call the internal method to complete the operation. int orderId = Order.Insert(transaction, blockOrderId, blotterId, accountId, securityId, settlementId, brokerId, transactionTypeCode, timeInForceCode, orderTypeCode, conditionCode, ref rowVersion, isAgency, quantity, price1, price2, note); // Return values. remoteMethod.Parameters.ReturnValue("rowVersion", rowVersion); remoteMethod.Parameters.ReturnValue(orderId); } } catch (SqlException sqlException) { // Every exception from the SQL server call is packed into the 'RemoteMethod' structure and returned to the caller. for (IEnumerator iEnumerator = sqlException.Errors.GetEnumerator(); iEnumerator.MoveNext(); remoteMethod.Exceptions.Add(((SqlError)(iEnumerator.Current)).Message)) { } } catch (Exception exception) { // This will pass the general exception back to the caller. remoteMethod.Exceptions.Add(exception); } }
/// <summary>Inserts a Execution record using Metadata Parameters.</summary> /// <param name="transaction">Commits or rejects a set of commands as a unit.</param> /// <param name="remoteMethod">Contains the metadata parameters and exceptions for this command.</param> public static void Insert(Transaction transaction, RemoteMethod remoteMethod) { try { // Extract the parameters from the command batch. int blockOrderId = remoteMethod.Parameters.GetRequiredInt32("blockOrderId"); int brokerId = remoteMethod.Parameters.GetRequiredInt32("brokerId"); System.Decimal quantity = remoteMethod.Parameters.GetRequiredDecimal("quantity"); System.Decimal price = remoteMethod.Parameters.GetRequiredDecimal("price"); object commission = remoteMethod.Parameters.GetOptionalDecimal("commission"); object accruedInterest = remoteMethod.Parameters.GetOptionalDecimal("accruedInterest"); object userFee0 = remoteMethod.Parameters.GetOptionalDecimal("userFee0"); object userFee1 = remoteMethod.Parameters.GetOptionalDecimal("userFee1"); object userFee2 = remoteMethod.Parameters.GetOptionalDecimal("userFee2"); object userFee3 = remoteMethod.Parameters.GetOptionalDecimal("userFee3"); System.DateTime tradeDate = remoteMethod.Parameters.GetRequiredDateTime("tradeDate"); System.DateTime settlementDate = remoteMethod.Parameters.GetRequiredDateTime("settlementDate"); // Make sure the parameters were parsed correctly before calling the internal method. This will prevent the method // from being called with bad data, but provides for error checking on all the parameters. if ((remoteMethod.HasExceptions == false)) { // The rowVersion is passed back to the caller in the event it's needed for additional commands in the batch. long rowVersion = long.MinValue; // Call the internal method to complete the operation. int executionId = Execution.Insert(transaction, blockOrderId, brokerId, ref rowVersion, quantity, price, commission, accruedInterest, userFee0, userFee1, userFee2, userFee3, tradeDate, settlementDate); // Return values. remoteMethod.Parameters.ReturnValue("rowVersion", rowVersion); remoteMethod.Parameters.ReturnValue(executionId); } } catch (SqlException sqlException) { // Every exception from the SQL server call is packed into the 'RemoteMethod' structure and returned to the caller. for (IEnumerator iEnumerator = sqlException.Errors.GetEnumerator(); iEnumerator.MoveNext(); remoteMethod.Exceptions.Add(((SqlError)(iEnumerator.Current)).Message)) { } } catch (Exception exception) { // This will pass the general exception back to the caller. remoteMethod.Exceptions.Add(exception); } }
/// <summary> /// Terminates the simulation of a price feed. /// </summary> /// <param name="transaction">Used to commit or reject one or more operations as a unit.</param> /// <param name="remoteMethod">A metadata description of the method to be executed.</param> public static void Stop(Transaction transaction, RemoteMethod remoteMethod) { // If the user doesn't provide an explit name of a thread, the last one will be terminated. string defaultThreadName = string.Format("Market Price {0}", Price.simulatorCounter); // Extract the method parameters. string name = remoteMethod.Parameters.GetRequiredString("name", defaultThreadName); // Find the thread based on the name and terminate it. Thread thread = (Thread)marketThreadTable[name]; if (thread == null) { throw new Exception(string.Format("There is no thread named {0}.", name)); } thread.Abort(); // This keeps track of the number of threads running. --Price.simulatorCounter; }
/// <summary> /// Adds an order to a block order. /// </summary> /// <param name="configurationId">Defines which external fields are used to identify an object.</param> /// <param name="accountId">The destination account for the order.</param> /// <param name="tif">Specifies a time limit on the order.</param> /// <param name="quantity">The number of units to be traded.</param> /// <returns>An internal identifier used to track the order.</returns> public int AddOrder(Account account, TIF tif, decimal quantity) { RemoteBatch remoteBatch = new RemoteBatch(); RemoteAssembly remoteAssembly = remoteBatch.Assemblies.Add("Service.Trading"); RemoteType remoteType = remoteAssembly.Types.Add("Shadows.WebService.Trading.Order"); RemoteMethod remoteMethod = remoteType.Methods.Add("Insert"); remoteMethod.Parameters.Add("orderId", DataType.Int, Direction.ReturnValue); remoteMethod.Parameters.Add("blockOrderId", this.blockOrderId); remoteMethod.Parameters.Add("accountId", account.AccountId); remoteMethod.Parameters.Add("securityId", this.Security.SecurityId); remoteMethod.Parameters.Add("settlementId", this.Settlement.SecurityId); remoteMethod.Parameters.Add("timeInForceCode", (int)tif); remoteMethod.Parameters.Add("transactionTypeCode", (int)this.transactionType); remoteMethod.Parameters.Add("orderTypeCode", (int)PricedAt.Market); remoteMethod.Parameters.Add("quantity", quantity); ClientMarketData.Execute(remoteBatch); return (int)remoteMethod.Parameters["orderId"].Value; }
/// <summary> /// Creates a batch command to delete a proposed order and it's links. /// </summary> /// <param name="remoteBatch"></param> /// <param name="remoteTransaction"></param> /// <param name="parentProposedOrder"></param> public static void Delete(RemoteBatch remoteBatch, RemoteTransaction remoteTransaction, ClientMarketData.ProposedOrderRow parentProposedOrder) { // These define the assembly and the types within those assemblies that will be used to create the proposed orders on // the middle tier. RemoteAssembly remoteAssembly = remoteBatch.Assemblies.Add("Service.Core"); RemoteType proposedOrderType = remoteAssembly.Types.Add("Shadows.WebService.Core.ProposedOrder"); RemoteType proposedOrderTreeType = remoteAssembly.Types.Add("Shadows.WebService.Core.ProposedOrderTree"); // Proposed orders have a hierarchy. For example, orders for equities will be linked to foreach (ClientMarketData.ProposedOrderTreeRow proposedOrderTree in parentProposedOrder.GetProposedOrderTreeRowsByFKProposedOrderProposedOrderTreeParentId()) { // Create a command to delete the relationship between the parent and child. RemoteMethod deleteRelation = proposedOrderTreeType.Methods.Add("Delete"); deleteRelation.Transaction = remoteTransaction; deleteRelation.Parameters.Add("rowVersion", proposedOrderTree.RowVersion); deleteRelation.Parameters.Add("parentId", proposedOrderTree.ParentId); deleteRelation.Parameters.Add("childId", proposedOrderTree.ChildId); // This relatioship will give us access to the child proposed order. ClientMarketData.ProposedOrderRow childProposedOrder = proposedOrderTree.ProposedOrderRowByFKProposedOrderProposedOrderTreeChildId; // Create a command to delete the child proposed order. RemoteMethod deleteChild = proposedOrderType.Methods.Add("Delete"); deleteChild.Transaction = remoteTransaction; deleteChild.Parameters.Add("rowVersion", childProposedOrder.RowVersion); deleteChild.Parameters.Add("proposedOrderId", childProposedOrder.ProposedOrderId); } // Create a command to delete the parent proposed order. RemoteMethod deleteParent = proposedOrderType.Methods.Add("Delete"); deleteParent.Transaction = remoteTransaction; deleteParent.Parameters.Add("rowVersion", parentProposedOrder.RowVersion); deleteParent.Parameters.Add("proposedOrderId", parentProposedOrder.ProposedOrderId); }
/// <summary>Updates a Placement record using Metadata Parameters.</summary> /// <param name="transaction">Commits or rejects a set of commands as a unit</param> /// <param name="remoteMethod">Contains the parameters and exceptions for this command.</param> public static void Update(Transaction transaction, RemoteMethod remoteMethod) { try { // Extract the parameters from the command batch. int placementId = remoteMethod.Parameters.GetRequiredInt32("placementId"); object blockOrderId = remoteMethod.Parameters.GetOptionalInt32("blockOrderId"); object brokerId = remoteMethod.Parameters.GetOptionalInt32("brokerId"); object timeInForceCode = remoteMethod.Parameters.GetOptionalInt32("timeInForceCode"); object orderTypeCode = remoteMethod.Parameters.GetOptionalInt32("orderTypeCode"); long rowVersion = remoteMethod.Parameters.GetRequiredInt64("rowVersion"); object isRouted = remoteMethod.Parameters.GetOptionalBoolean("isRouted"); object quantity = remoteMethod.Parameters.GetOptionalDecimal("quantity"); object price1 = remoteMethod.Parameters.GetOptionalDecimal("price1"); object price2 = remoteMethod.Parameters.GetOptionalDecimal("price2"); // Make sure the parameters were parsed correctly before calling the internal method. This will prevent the method // from being called with bad data, but provides for error checking on all the parameters. if ((remoteMethod.HasExceptions == false)) { // Call the internal method to complete the operation. Placement.Update(transaction, placementId, blockOrderId, brokerId, timeInForceCode, orderTypeCode, ref rowVersion, isRouted, quantity, price1, price2); // Return values. remoteMethod.Parameters.ReturnValue("rowVersion", rowVersion); } } catch (SqlException sqlException) { // Every exception from the SQL server call is packed into the 'RemoteMethod' structure and returned to the caller. for (IEnumerator iEnumerator = sqlException.Errors.GetEnumerator(); iEnumerator.MoveNext(); remoteMethod.Exceptions.Add(((SqlError)(iEnumerator.Current)).Message)) { } } catch (Exception exception) { // This will pass the general exception back to the caller. remoteMethod.Exceptions.Add(exception); } }
/// <summary> /// Creates a temporary, empty model portfolio. /// </summary> /// <param name="accountRow">An account record.</param> /// <returns>A batch of commands that will create the empty model.</returns> private static ModelBatch CreateEmptyModel(ClientMarketData.AccountRow accountRow) { // Create the batch and fill it in with the assembly and type needed for this function. ModelBatch modelBatch = new ModelBatch(); RemoteAssembly remoteAssembly = modelBatch.Assemblies.Add("Service.Core"); RemoteType remoteType = remoteAssembly.Types.Add("Shadows.WebService.Core.Model"); // This method will insert a generic, empty, security level model. RemoteMethod insertModel = remoteType.Methods.Add("Insert"); insertModel.Parameters.Add("modelId", DataType.Int, Direction.ReturnValue); insertModel.Parameters.Add("rowVersion", DataType.Long, Direction.Output); insertModel.Parameters.Add("modelTypeCode", ModelType.Security); insertModel.Parameters.Add("name", "Untitled"); insertModel.Parameters.Add("schemeId", accountRow.SchemeId); insertModel.Parameters.Add("algorithmId", Algorithm.SecurityRebalancer); insertModel.Parameters.Add("temporary", true); // Save the reference to the 'modelId' return parameter. modelBatch.ModelIdParameter = insertModel.Parameters["modelId"]; // This batch will create an empty, position based model. return(modelBatch); }
public void Remove() { long rowVersion = long.MinValue; try { // Lock the tables. Debug.Assert(!ClientMarketData.AreLocksHeld); ClientMarketData.ViolationLock.AcquireReaderLock(CommonTimeout.LockWait); // Prevent duplicates. ClientMarketData.ViolationRow violationRow = ClientMarketData.Violation.FindByViolationId(this.violationId); if (violationRow == null) { return; } rowVersion = violationRow.RowVersion; } finally { // Release the table locks. if (ClientMarketData.ViolationLock.IsReaderLockHeld) { ClientMarketData.ViolationLock.ReleaseReaderLock(); } Debug.Assert(!ClientMarketData.AreLocksHeld); } RemoteAssembly remoteAssembly = CommandBatch.Assemblies.Add("Service.Core"); RemoteType remoteType = remoteAssembly.Types.Add("Shadows.WebService.Core.Violation"); RemoteMethod remoteMethod = remoteType.Methods.Add("Delete"); remoteMethod.Parameters.Add("violationId", this.violationId); remoteMethod.Parameters.Add("rowVersion", rowVersion); }
public static void Distribute(int blockOrderId) { // This batch will be filled in with the allocations. RemoteBatch remoteBatch = null; try { // Lock all the tables that we'll reference while building a blotter document. Debug.Assert(!ClientMarketData.AreLocksHeld); ClientMarketData.AllocationLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.BlockOrderLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.ExecutionLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.OrderLock.AcquireReaderLock(CommonTimeout.LockWait); // Find the block order that is to be allocated. ClientMarketData.BlockOrderRow blockOrderRow = ClientMarketData.BlockOrder.FindByBlockOrderId(blockOrderId); if (blockOrderRow == null) { throw new Exception(String.Format("Block Id {0} doesn't exist", blockOrderId)); } // Aggregate the total quantity ordered. This becomes the demoninator for the pro-rata calculation. decimal orderedQuantity = 0.0M; foreach (ClientMarketData.OrderRow orderRow in blockOrderRow.GetOrderRows()) { orderedQuantity += orderRow.Quantity; } // These values will total up all the executions posted against this block order. The pro-rata // allocation will divide all the executions up against the ratio of the quantity ordered against the // total quantity ordered. The price is an average price of all the executions. decimal executedQuantity = 0.0M; decimal executedPrice = 0.0M; decimal executedCommission = 0.0M; decimal executedAccruedInterest = 0.0M; decimal executedUserFee0 = 0.0M; decimal executedUserFee1 = 0.0M; decimal executedUserFee2 = 0.0M; decimal executedUserFee3 = 0.0M; DateTime tradeDate = DateTime.MinValue; DateTime settlementDate = DateTime.MinValue; // Total up all the executions against this block. foreach (ClientMarketData.ExecutionRow executionRow in blockOrderRow.GetExecutionRows()) { executedQuantity += executionRow.Quantity; executedPrice += executionRow.Price * executionRow.Quantity; executedCommission += executionRow.Commission; executedAccruedInterest += executionRow.AccruedInterest; executedUserFee0 += executionRow.UserFee0; executedUserFee1 += executionRow.UserFee1; executedUserFee2 += executionRow.UserFee2; executedUserFee3 += executionRow.UserFee3; tradeDate = executionRow.TradeDate; settlementDate = executionRow.SettlementDate; } // Calculate the average price. decimal averagePrice = Math.Round((executedQuantity > 0.0M) ? executedPrice / executedQuantity : 0.0M, 2); // These values are used to keep track of how much has been allocated. Because of the nature of a // pro-rata allocation, there will be an odd remainder after the allocation is finished. We will // arbitrarily pick the last order in the block order and give it the remainer of the order. To do that, // totals have to be kept of all the allocations that have been created before the last one. decimal allocatedQuantity = 0.0M; decimal allocatedCommission = 0.0M; decimal allocatedAccruedInterest = 0.0M; decimal allocatedUserFee0 = 0.0M; decimal allocatedUserFee1 = 0.0M; decimal allocatedUserFee2 = 0.0M; decimal allocatedUserFee3 = 0.0M; // Put all the allocations in a single batch. remoteBatch = new RemoteBatch(); RemoteAssembly remoteAssembly = remoteBatch.Assemblies.Add("Service.Core"); RemoteType remoteType = remoteAssembly.Types.Add("Shadows.WebService.Core.Allocation"); // Allocate the order back to the original accounts. Because odd values can be generated when dividing by the // pro-rata value, the last order will get the remaining portions of the execution. int orderCounter = blockOrderRow.GetOrderRows().Length; foreach (ClientMarketData.OrderRow orderRow in blockOrderRow.GetOrderRows()) { decimal quantity; decimal commission; decimal accruedInterest; decimal userFee0; decimal userFee1; decimal userFee2; decimal userFee3; // The last account in the order is arbitrarily given the remaining parts of the execution. if (--orderCounter == 0) { quantity = executedQuantity - allocatedQuantity; commission = executedCommission - allocatedCommission; accruedInterest = executedAccruedInterest = allocatedAccruedInterest; userFee0 = executedUserFee0 - allocatedUserFee0; userFee1 = executedUserFee1 - allocatedUserFee1; userFee2 = executedUserFee2 - allocatedUserFee2; userFee3 = executedUserFee3 - allocatedUserFee3; } else { // Calcuation the proportion of the trade destined for the current order. The proportion is // based on the amount of the original order against the block total. quantity = Math.Round(executedQuantity * orderRow.Quantity / orderedQuantity, 0); commission = Math.Round(executedCommission * orderRow.Quantity / orderedQuantity, 2); accruedInterest = Math.Round(executedAccruedInterest * orderRow.Quantity / orderedQuantity, 2); userFee0 = Math.Round(executedUserFee0 * orderRow.Quantity / orderedQuantity, 2); userFee1 = Math.Round(executedUserFee1 * orderRow.Quantity / orderedQuantity, 2); userFee2 = Math.Round(executedUserFee2 * orderRow.Quantity / orderedQuantity, 2); userFee3 = Math.Round(executedUserFee3 * orderRow.Quantity / orderedQuantity, 2); } // Keep a running total of the amount allocated so far. This will be used to calculate the last order's // portion when the loop has finished. allocatedQuantity += quantity; allocatedCommission += commission; allocatedAccruedInterest += accruedInterest; allocatedUserFee0 += userFee0; allocatedUserFee1 += userFee1; allocatedUserFee2 += userFee2; allocatedUserFee3 += userFee3; // If the allocation has a positive quantity to register, then post it to the server. if (quantity > 0.0M) { // Call the web service to add the new execution. RemoteMethod remoteMethod = remoteType.Methods.Add("Insert"); remoteMethod.Parameters.Add("blockOrderId", orderRow.BlockOrderId); remoteMethod.Parameters.Add("accountId", orderRow.AccountId); remoteMethod.Parameters.Add("securityId", orderRow.SecurityId); remoteMethod.Parameters.Add("settlementId", orderRow.SettlementId); remoteMethod.Parameters.Add("positionTypeCode", orderRow.PositionTypeCode); remoteMethod.Parameters.Add("transactionTypeCode", orderRow.TransactionTypeCode); remoteMethod.Parameters.Add("quantity", quantity); remoteMethod.Parameters.Add("price", averagePrice); remoteMethod.Parameters.Add("commission", commission); remoteMethod.Parameters.Add("accruedInterest", accruedInterest); remoteMethod.Parameters.Add("userFee0", userFee0); remoteMethod.Parameters.Add("userFee1", userFee1); remoteMethod.Parameters.Add("userFee2", userFee2); remoteMethod.Parameters.Add("userFee3", userFee3); remoteMethod.Parameters.Add("tradeDate", tradeDate); remoteMethod.Parameters.Add("settlementDate", settlementDate); remoteMethod.Parameters.Add("createdTime", DateTime.Now); remoteMethod.Parameters.Add("createdLoginId", ClientPreferences.LoginId); remoteMethod.Parameters.Add("modifiedTime", DateTime.Now); remoteMethod.Parameters.Add("modifiedLoginId", ClientPreferences.LoginId); } } } catch (Exception exception) { // This signals that the batch isn't valid and shouldn't be sent. remoteBatch = null; // This will catch all remaining exceptions. Debug.WriteLine(exception.Message); } finally { // Release the locks obtained to produce the blotter report. if (ClientMarketData.AllocationLock.IsReaderLockHeld) { ClientMarketData.AllocationLock.ReleaseReaderLock(); } if (ClientMarketData.BlockOrderLock.IsReaderLockHeld) { ClientMarketData.BlockOrderLock.ReleaseReaderLock(); } if (ClientMarketData.ExecutionLock.IsReaderLockHeld) { ClientMarketData.ExecutionLock.ReleaseReaderLock(); } if (ClientMarketData.OrderLock.IsReaderLockHeld) { ClientMarketData.OrderLock.ReleaseReaderLock(); } Debug.Assert(!ClientMarketData.AreLocksHeld); } // Once the locks are release, the batch can be sent to the server. if (remoteBatch != null) { ClientMarketData.Send(remoteBatch); } }
/// <summary> /// Load up an assembly section of a batch. /// </summary> /// <param name="assemblyNode"></param> private static void LoadAssembly(XmlNode assemblyNode, int batchSize) { // Ignore Comment Nodes. if (assemblyNode.NodeType == XmlNodeType.Comment) { return; } // Add an Assembly specifier to the batch. This essentially describes the DLL where the methods are found. string assemblyName = assemblyNode.Attributes["name"].Value; // Each assembly can have one or more Objects (or Types) which can be instantiated. The batch command // processing can call static methods belonging to the instantiated object. foreach (XmlNode typeNode in assemblyNode.SelectNodes("type")) { // Ignore Comment Nodes. if (typeNode.NodeType == XmlNodeType.Comment) { continue; } // Loading the database involves creating a batch of commands and sending them off as a transaction. // This gives the server a chance to pipeline a large chunk of processing, without completely locking // up the server for the entire set of data. This will construct a header for the command batch which // gives information about which assembly contains the class that is used to load the data. string typeName = typeNode.Attributes["name"].Value; // Attach each method and it's parameters to the command batch. foreach (XmlNode methodNode in typeNode.SelectNodes("method")) { // Ignore Comment Nodes. if (methodNode.NodeType == XmlNodeType.Comment) { continue; } // The 'remoteBatch' will be cleared after it is sent to the server. Make sure a batch exists before adding // methods and parameters to it. if (remoteBatch == null) { // Loading the database involves creating a batch of commands and sending them off as a transaction. This // gives the server a chance to pipeline a large chunk of processing, without completely locking up the // server for the entire set of data. This will create a batch for the next bunch of commands. remoteBatch = new RemoteBatch(); remoteTransaction = remoteBatch.Transactions.Add(); // This counts the number of records placed in the batch. batchCounter = 0; } if (remoteAssembly == null || remoteAssembly.Name != assemblyName) { remoteAssembly = remoteBatch.Assemblies.Add(assemblyName); } if (remoteType == null || remoteType.Name != typeName) { remoteType = remoteAssembly.Types.Add(typeName); } // Each method is part of the transaction defined by the tagged outline structure of the input // file. RemoteMethod remoteMethod = remoteType.Methods.Add(methodNode.Attributes["name"].Value); remoteMethod.Transaction = remoteTransaction; // Load each of the parameters into the method structure. foreach (XmlNode parameterNode in methodNode.ChildNodes) { // Ignore Comment Nodes. if (parameterNode.NodeType == XmlNodeType.Comment) { continue; } // Add the next parameter to the method. remoteMethod.Parameters.Add(parameterNode.Name, parameterNode.InnerText); } // One more record for the grand total, one more record for the number in the current batch. recordCounter++; batchCounter++; // This will check to see if it's time to send the batch. A batch is sent when the 'batchSize' has been // reached, or if the last record has just been converted into a command. if (batchSize != 0 && recordCounter % batchSize == 0) { SendBatch(); } } } }
static int Main(string[] args) { // If this flag is set during the processing of the file, the program will exit with an error code. bool hasErrors = false; try { // Defaults assemblyName = "Service.External"; namespaceName = "Shadows.WebService.External"; externalConfigurationCode = "DEFAULT"; argumentState = ArgumentState.FileName; // Parse the command line for arguments. foreach (string argument in args) { // Decode the current argument into a state. if (argument == "-c") { argumentState = ArgumentState.ConfigurationCode; continue; } if (argument == "-i") { argumentState = ArgumentState.FileName; continue; } if (argument == "-id") { argumentState = ArgumentState.StylesheetId; continue; } if (argument == "-t") { argumentState = ArgumentState.StylesheetTypeCode; continue; } // The parsing state will determine which variable is read next. switch (argumentState) { // Read the command line argument into the proper variable based on the parsing state. case ArgumentState.ConfigurationCode: externalConfigurationCode = argument; break; case ArgumentState.StylesheetTypeCode: stylesheetTypeCode = argument; break; case ArgumentState.FileName: fileName = argument; break; case ArgumentState.Name: name = argument; break; case ArgumentState.StylesheetId: StylesheetId = argument; break; } // The default state for the parser is to look for a file name. argumentState = ArgumentState.FileName; } // If no file name was specified, we return an error. if (fileName == null) { throw new Exception("Usage: Loader.Stylesheet -i <FileName>"); } // Load up an XML document with the contents of the file specified on the command line. XmlDocument stylesheet = new XmlDocument(); stylesheet.Load(fileName); // The XML document has several nodes that need to be read -- and then removed -- that contain attributes of the // stylesheet. These nodes can be found easily using the XSL Path functions which need a namespace manager to sort // out the tag prefixes. XmlNamespaceManager namespaceManager = new XmlNamespaceManager(stylesheet.NameTable); namespaceManager.AddNamespace("xsl", "http://www.w3.org/1999/XSL/Transform"); namespaceManager.AddNamespace("sss", "urn:schemas-shadows-com:shadows:stylesheet"); // The spreadhseet source has several nodes which contain information about how the data in the XML document should // be loaded into the server, such as the stylesheet identifier, the name and the stylesheet style. They are found // at this node. After these information nodes have been read, they are removed from the stylesheet source. XmlNode stylesheetNode = stylesheet.SelectSingleNode("xsl:stylesheet", namespaceManager); if (stylesheetNode == null) { throw new Exception("Syntax Error: missing stylesheet declaration."); } // Find the StylesheetId node. XmlNode StylesheetIdNode = stylesheetNode.SelectSingleNode("sss:stylesheetId", namespaceManager); if (StylesheetIdNode == null) { throw new Exception("Syntax Error: missing StylesheetId declaration."); } // Find the StylesheetStyle node. XmlNode stylesheetTypeCodeNode = stylesheetNode.SelectSingleNode("sss:stylesheetTypeCode", namespaceManager); if (stylesheetTypeCodeNode == null) { throw new Exception("Syntax Error: missing StylesheetStyle declaration."); } // Find the name node. XmlNode nameNode = stylesheetNode.SelectSingleNode("sss:name", namespaceManager); if (nameNode == null) { throw new Exception("Syntax Error: missing name declaration."); } // Extract the data from the XML nodes. StylesheetId = StylesheetIdNode.InnerText; stylesheetTypeCode = stylesheetTypeCodeNode.InnerText; name = nameNode.InnerText; // Remove the stylesheet nodes from the XSL spreadsheet before loading it into the server. stylesheetNode.RemoveChild(StylesheetIdNode); stylesheetNode.RemoveChild(stylesheetTypeCodeNode); stylesheetNode.RemoveChild(nameNode); // Create a command to load the stylesheet from the data loaded from the file. RemoteBatch remoteBatch = new RemoteBatch(); RemoteAssembly remoteAssembly = remoteBatch.Assemblies.Add(assemblyName); RemoteType remoteType = remoteAssembly.Types.Add(string.Format("{0}.{1}", namespaceName, "Stylesheet")); RemoteMethod remoteMethod = remoteType.Methods.Add("Load"); remoteMethod.Parameters.Add("StylesheetId", StylesheetId); remoteMethod.Parameters.Add("stylesheetTypeCode", stylesheetTypeCode); remoteMethod.Parameters.Add("name", name); remoteMethod.Parameters.Add("text", stylesheet.InnerXml); // Create a new web client that will serve as the connection point to the server and call the web services to // execute the command batch. WebClient webClient = new WebClient(); remoteBatch.Merge(webClient.Execute(remoteBatch)); // Display the each of the exceptions and set a global flag that shows that there was an exception to the normal // execution. if (remoteBatch.HasExceptions) { foreach (RemoteException exception in remoteBatch.Exceptions) { Console.WriteLine(String.Format("{0}: {1}", remoteMethod.Parameters["StylesheetId"].Value, exception.Message)); } hasErrors = true; } } catch (Exception exception) { // Show the system error and exit with an error. Console.WriteLine(exception.Message); hasErrors = true; } // Any errors will cause an abnormal exit. if (hasErrors) { return(1); } // Display the template that was loaded and exit with a successful code. Console.WriteLine(String.Format("{0} Stylesheet: {1}, Loaded", DateTime.Now.ToString("u"), name)); return(0); }
private void DragDropHandler(params object[] arguments) { ObjectNode toNode = (ObjectNode)arguments[0]; ObjectNode fromNode = (ObjectNode)arguments[1]; ObjectNode childNode = (ObjectNode)arguments[2]; // Make sure the user has selected a valid source and destination for the operation. It's illegal to move the node // 1. To the root of the tree // 2. From the root of the tree if (toNode == null || fromNode == null) { return; } // Don't allow for circular references. try { // Lock the tables needed for this operation. Debug.Assert(!ClientMarketData.AreLocksHeld); ClientMarketData.ObjectLock.AcquireReaderLock(CommonTimeout.LockWait); // It's critical that circular references aren't created, either by accident or design. First, find the object // record associated with the destination node. ClientMarketData.ObjectRow parentRow = ClientMarketData.Object.FindByObjectId(toNode.ObjectId); if (parentRow == null) { throw new Exception("This object has been deleted"); } // This is the object that is being dragged. Find the row ClientMarketData.ObjectRow childRow = ClientMarketData.Object.FindByObjectId(childNode.ObjectId); if (childRow == null) { throw new Exception("This object has been deleted"); } if (Shadows.Quasar.Common.Relationship.IsChildObject(childRow, parentRow)) { MessageBox.Show(this.TopLevelControl, "This would create a circular references.", "Quasar Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } catch (Exception exception) { // Write the error and stack trace out to the debug listener Debug.WriteLine(String.Format("{0}, {1}", exception.Message, exception.StackTrace)); } finally { // Release table locks. if (ClientMarketData.ObjectLock.IsReaderLockHeld) { ClientMarketData.ObjectLock.ReleaseReaderLock(); } Debug.Assert(!ClientMarketData.AreLocksHeld); } // Any commands created below will be constructed in this object and sent to the server for execution. RemoteBatch remoteBatch = new RemoteBatch(); // Change the default model of an account. When the destination is an account group, account or sub account and the // source is a model, a command will be constructed to change the default model. if (toNode.ObjectTypeCode == ObjectType.Account && dragNode.ObjectTypeCode == ObjectType.Model) { try { // Lock the tables needed for this operation. Debug.Assert(!ClientMarketData.AreLocksHeld); ClientMarketData.AccountLock.AcquireReaderLock(CommonTimeout.LockWait); // Find the account used, throw an error if it's been deleted. ClientMarketData.AccountRow accountRow; if ((accountRow = ClientMarketData.Account.FindByAccountId(toNode.ObjectId)) == null) { throw new Exception("This account has been deleted"); } // Construct a command to change the default model associated with the account. RemoteAssembly remoteAssembly = remoteBatch.Assemblies.Add("Service.Core"); RemoteType remoteType = remoteAssembly.Types.Add("Shadows.WebService.Core.Account"); RemoteMethod remoteMethod = remoteType.Methods.Add("Update"); remoteMethod.Parameters.Add("rowVersion", accountRow.RowVersion); remoteMethod.Parameters.Add("accountId", accountRow.AccountId); remoteMethod.Parameters.Add("modelId", dragNode.ObjectId); } catch (Exception exception) { // Write the error and stack trace out to the debug listener Debug.WriteLine(String.Format("{0}, {1}", exception.Message, exception.StackTrace)); } finally { // Release table locks. if (ClientMarketData.AccountLock.IsReaderLockHeld) { ClientMarketData.AccountLock.ReleaseReaderLock(); } Debug.Assert(!ClientMarketData.AreLocksHeld); } } else { // If we made it here, the drag-and-drop is interpreted as a command to move a child from one parent to another. try { // Lock the tables needed for this operation. Debug.Assert(!ClientMarketData.AreLocksHeld); ClientMarketData.ObjectTreeLock.AcquireReaderLock(CommonTimeout.LockWait); // Extract the primary identifiers from the user interface nodes. int fromId = fromNode.ObjectId; int toId = toNode.ObjectId; int childId = dragNode.ObjectId; // Find the object in the data model and make sure it still exists. ClientMarketData.ObjectTreeRow objectTreeRow = ClientMarketData.ObjectTree.FindByParentIdChildId(fromNode.ObjectId, dragNode.ObjectId); if (objectTreeRow == null) { throw new Exception("This relationship has been deleted by someone else."); } // Moving a child object from one parent to another must be accomplished as a transaction. Otherwise, an // orhpan object will be created if the operation fails midway through. RemoteTransaction remoteTransaction = remoteBatch.Transactions.Add(); RemoteAssembly remoteAssembly = remoteBatch.Assemblies.Add("Service.Core"); RemoteType remoteType = remoteAssembly.Types.Add("Shadows.WebService.Core.ObjectTree"); // Construct a command delete the old parent relation. RemoteMethod deleteObjectTree = remoteType.Methods.Add("Delete"); deleteObjectTree.Transaction = remoteTransaction; deleteObjectTree.Parameters.Add("rowVersion", objectTreeRow.RowVersion); deleteObjectTree.Parameters.Add("parentId", fromId); deleteObjectTree.Parameters.Add("childId", childId); // Construct a command insert a new parent relation. RemoteMethod insertObjectTree = remoteType.Methods.Add("Insert"); insertObjectTree.Transaction = remoteTransaction; insertObjectTree.Parameters.Add("parentId", toId); insertObjectTree.Parameters.Add("childId", childId); } catch (Exception exception) { // Write the error and stack trace out to the debug listener Debug.WriteLine(String.Format("{0}, {1}", exception.Message, exception.StackTrace)); } finally { // Release table locks. if (ClientMarketData.ObjectTreeLock.IsReaderLockHeld) { ClientMarketData.ObjectTreeLock.ReleaseReaderLock(); } Debug.Assert(!ClientMarketData.AreLocksHeld); } } // If the command batch was built successfully, then execute it. if (remoteBatch != null) { try { // Call the web server to rename the object on the database. Note that this method must be called when there are // no locks to prevent deadlocking. That is why it appears in it's own 'try/catch' block. ClientMarketData.Execute(remoteBatch); } catch (BatchException batchException) { // Display each error in the batch. foreach (RemoteException remoteException in batchException.Exceptions) { MessageBox.Show(remoteException.Message, "Quasar Error"); } } } }
/// <summary> /// Event handler for changing the name of a label. /// </summary> /// <param name="sender">The window control that generated the 'LabelEdit' event.</param> /// <param name="e">Event Parameters used to control the actions taken by the event handler.</param> private void treeView_AfterLabelEdit(object sender, System.Windows.Forms.NodeLabelEditEventArgs e) { // The TreeView has a bug in it: if you leave the edit mode without typing anything, the returned text of the control // will be an empty string. Since we don't want to bother the server or the user with this nonsense, we'll filter out // the possiblity here. if (e.Label == null) { e.CancelEdit = true; return; } // Extract the object's properties from the node. ObjectNode objectNode = (ObjectNode)e.Node; // This command batch is constructed below and sent to the server for execution. RemoteBatch remoteBatch = new RemoteBatch(); // This will insure that table locks are cleaned up. try { // Lock the table Debug.Assert(!ClientMarketData.AreLocksHeld); ClientMarketData.ObjectLock.AcquireReaderLock(CommonTimeout.LockWait); // Find the object in the data model and make sure it still exists. ClientMarketData.ObjectRow objectRow = ClientMarketData.Object.FindByObjectId(objectNode.ObjectId); if (objectRow == null) { throw new Exception("This object has been deleted."); } // Construct a command to rename the object. RemoteAssembly remoteAssembly = remoteBatch.Assemblies.Add("Service.Core"); RemoteType remoteType = remoteAssembly.Types.Add("Shadows.WebService.Core.Object"); RemoteMethod remoteMethod = remoteType.Methods.Add("Update"); remoteMethod.Parameters.Add("rowVersion", objectRow.RowVersion); remoteMethod.Parameters.Add("objectId", objectRow.ObjectId); remoteMethod.Parameters.Add("name", e.Label); } catch (Exception exception) { // Write the error and stack trace out to the debug listener Debug.WriteLine(String.Format("{0}, {1}", exception.Message, exception.StackTrace)); // Cancel the tree operation if we can't execute the command. The text in the tree control will revert to the // previous value. e.CancelEdit = true; } finally { // Release table locks. if (ClientMarketData.ObjectLock.IsReaderLockHeld) { ClientMarketData.ObjectLock.ReleaseReaderLock(); } Debug.Assert(!ClientMarketData.AreLocksHeld); } // If the command batch was built successfully, then execute it. If any part of it should fail, cancel the edit and // display the server errors. if (remoteBatch != null) { try { // Call the web server to rename the object on the database. Note that this method must be called when there are // no locks to prevent deadlocking. That is why it appears in it's own 'try/catch' block. ClientMarketData.Execute(remoteBatch); } catch (BatchException batchException) { // Undo the editing action. This will restore the name of the object to what it was before the operation. e.CancelEdit = true; // Display each error in the batch. foreach (RemoteException remoteException in batchException.Exceptions) { MessageBox.Show(remoteException.Message, "Quasar Error"); } } } }
public void Register <T>(Int16 methodHash, Action <T> method) { var methodCallback = new RemoteMethod(method.Method, method.Target); Register(methodHash, methodCallback); }
private void button1_Click(object sender, EventArgs e) { if (selectedPid == 0) { MessageBox.Show("Select a process first", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } RemoteMethod x = new RemoteMethod(selectedPid); object[] r = x.allocateCall(); if (!(bool)r[0]) { MessageBox.Show((string)r[1], "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } try { x.functionAddr = (IntPtr)int.Parse(textFunctionAddr.Text, System.Globalization.NumberStyles.HexNumber); } catch (Exception ex) { MessageBox.Show("Cannot parse function addr!!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } try { foreach (Control[] param in paramList) { x.paramList.Add(Convert.ToInt32(param[0].Text)); } } catch (Exception ex) { MessageBox.Show("Cannot parse params!!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } try { if (cEAX.Checked) { x.registerEAX = int.Parse(textEAX.Text, System.Globalization.NumberStyles.HexNumber); x.writeEAX = true; } if (cEBX.Checked) { x.registerEBX = int.Parse(textEBX.Text, System.Globalization.NumberStyles.HexNumber); x.writeEBX = true; } if (cECX.Checked) { x.registerECX = int.Parse(textECX.Text, System.Globalization.NumberStyles.HexNumber); x.writeECX = true; } if (cEDX.Checked) { x.registerEDX = int.Parse(textEDX.Text, System.Globalization.NumberStyles.HexNumber); x.writeEDX = true; } if (cESI.Checked) { x.registerESI = int.Parse(textESI.Text, System.Globalization.NumberStyles.HexNumber); x.writeESI = true; } } catch (Exception ex) { MessageBox.Show("Cannot parse registers!!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } r = x.Call(); if (!(bool)r[0]) { MessageBox.Show((string)r[1], "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } else { MessageBox.Show((string)r[1], "Success", MessageBoxButtons.OK, MessageBoxIcon.Information); } x.clearCall(); }
static int Main(string[] args) { // If this flag is set during the processing of the file, the program will exit with an error code. bool hasErrors = false; try { // Defaults batchSize = 100; assemblyName = "Service.External"; nameSpaceName = "Shadows.WebService.External"; // The command line parser is driven by different states that are triggered by the flags read. Unless a flag has been // read, the command line parser assumes that it's reading the file name from the command line. argumentState = ArgumentState.FileName; // Parse the command line for arguments. foreach (string argument in args) { // Decode the current argument into a state change (or some other action). if (argument == "-a") { argumentState = ArgumentState.Assembly; continue; } if (argument == "-b") { argumentState = ArgumentState.BatchSize; continue; } if (argument == "-n") { argumentState = ArgumentState.NameSpace; continue; } if (argument == "-i") { argumentState = ArgumentState.FileName; continue; } // The parsing state will determine which variable is read next. switch (argumentState) { case ArgumentState.Assembly: assemblyName = argument; break; case ArgumentState.BatchSize: batchSize = Convert.ToInt32(argument); break; case ArgumentState.FileName: fileName = argument; break; case ArgumentState.NameSpace: nameSpaceName = argument; break; } // The default state is to look for the input file name on the command line. argumentState = ArgumentState.FileName; } // Throw a usage message back at the user if no file name was given. if (fileName == null) { throw new Exception("Usage: Loader.Algorithm -i <FileName>"); } // Open up the file containing all the broker. BrokerReader brokerReader = new BrokerReader(fileName); // Create a new web client that will serve as the connection point to the server. WebClient webClient = new WebClient(); // Loading the database involves creating a batch of commands and sending them off as a transaction. This gives // the server a chance to pipeline a large chunk of processing, without completely locking up the server for the // entire set of data. This will construct a header for the command batch which gives information about which // assembly contains the class that is used to load the data. RemoteBatch remoteBatch = new RemoteBatch(); RemoteTransaction remoteTransaction = remoteBatch.Transactions.Add(); RemoteAssembly remoteAssembly = remoteBatch.Assemblies.Add(assemblyName); RemoteType remoteType = remoteAssembly.Types.Add(string.Format("{0}.{1}", nameSpaceName, "Broker")); // Read the file until an EOF is reached. while (true) { // This counter keeps track of the number of records sent. When the batch is full, it's sent to the server to be // executed as a single transaction. int batchCounter = 0; // Read the next broker from the input stream. A 'null' is returned when we've read past the end of file. Broker broker = brokerReader.ReadBroker(); if (broker != null) { // Construct a call to the 'Load' method to populate the broker record. RemoteMethod remoteMethod = remoteType.Methods.Add("Load"); remoteMethod.Transaction = remoteTransaction; remoteMethod.Parameters.Add("brokerId", broker.Symbol); remoteMethod.Parameters.Add("name", broker.Name); remoteMethod.Parameters.Add("symbol", broker.Symbol); } // This will check to see if it's time to send the batch. A batch is sent when the 'batchSize' has been // reached, or if the last record has just been converted into a command. if (++batchCounter % batchSize == 0 || broker == null) { // Call the web services to execute the command batch. remoteBatch.Merge(webClient.Execute(remoteBatch)); // Any error during the batch will terminate the execution of the remaining records in the data file. if (remoteBatch.HasExceptions) { // Display each error on the console. foreach (RemoteMethod remoteMethod in remoteBatch.Methods) { foreach (RemoteException remoteException in remoteMethod.Exceptions) { Console.WriteLine(String.Format("{0}: {1}", remoteMethod.Parameters["brokerId"].Value, remoteException.Message)); } } // This will signal the error exit from this loader. hasErrors = true; } // If the end of file was reached, break out of the loop and exit the application. if (broker == null) { break; } // After each batch has been send, check to see if there are additional records to be send. If so, // regenerate the remote batch and set up the header. remoteBatch = new RemoteBatch(); remoteTransaction = remoteBatch.Transactions.Add(); remoteAssembly = remoteBatch.Assemblies.Add(assemblyName); remoteType = remoteAssembly.Types.Add(string.Format("{0}.{1}", nameSpaceName, "Broker")); } } } catch (Exception exception) { // Show the system error and exit with an error. Console.WriteLine(exception.Message); hasErrors = true; } // Any errors will cause an abnormal exit. if (hasErrors) { return(1); } // Write a status message when a the file is loaded successfully. Console.WriteLine(String.Format("{0} Data: Brokers, Loaded", DateTime.Now.ToString("u"))); // If we reached here, the file was imported without issue. return(0); }
/// <summary> /// Creates a temporary model based on the current sector level targets. /// </summary> /// <param name="accountRow">An account used as a basis for the targets.</param> /// <param name="schemeRow">The scheme used to select sector targets.</param> /// <returns>A batch of commands that will create a model containing the current sector weights of the account.</returns> private static ModelBatch CreateSectorSelfModel(ClientMarketData.AccountRow accountRow, ClientMarketData.SchemeRow schemeRow) { // This command batch will create a temporary model and populate it with the current position level percentages as the // target values. ModelBatch modelBatch = new ModelBatch(); RemoteTransaction remoteTransaction = modelBatch.Transactions.Add(); RemoteAssembly remoteAssembly = modelBatch.Assemblies.Add("Service.Core"); RemoteType remoteType = remoteAssembly.Types.Add("Shadows.WebService.Core.Model"); // Create the temporary model. RemoteMethod insertModel = remoteType.Methods.Add("Insert"); insertModel.Parameters.Add("modelId", DataType.Int, Direction.ReturnValue); insertModel.Parameters.Add("rowVersion", DataType.Long, Direction.Output); insertModel.Parameters.Add("modelTypeCode", ModelType.Sector); insertModel.Parameters.Add("name", "Untitled"); insertModel.Parameters.Add("schemeId", schemeRow.SchemeId); insertModel.Parameters.Add("algorithmId", Algorithm.SectorMergeRebalancer); insertModel.Parameters.Add("temporary", true); // The 'Self Sector' uses the market value of all the account and sub-account. decimal accountMarketValue = MarketValue.Calculate(accountRow.CurrencyRow, accountRow, MarketValueFlags.EntirePosition | MarketValueFlags.IncludeChildAccounts); // No need to construct a model if the account market value is zero. if (accountMarketValue != 0.0M) { // Create a new outline for the model to follow. This will collect the tax lots, proposed orders, orders // and allocations into industry classification sectors. Common.Appraisal appraisal = new Common.Appraisal(accountRow, schemeRow, true); // The object Type for this operation. RemoteType sectorTargetType = remoteAssembly.Types.Add("Shadows.WebService.Core.SectorTarget"); // Now that we have an outline to follow, we are going to run through each of the sectors, calculate the market // value, and create an entry in the temporary model for that sector and it's current weight of the overall market // value. foreach (AppraisalSet.SchemeRow driverScheme in appraisal.Scheme) { foreach (AppraisalSet.ObjectTreeRow driverTree in driverScheme.ObjectRow.GetObjectTreeRowsByFKObjectObjectTreeParentId()) { foreach (AppraisalSet.SectorRow driverSector in driverTree.ObjectRowByFKObjectObjectTreeChildId.GetSectorRows()) { // This sector is the destination for the market value calculation. ClientMarketData.SectorRow sectorRow = ClientMarketData.Sector.FindBySectorId(driverSector.SectorId); // Calculate the market value of all the securities held by all the accounts in the current sector. decimal sectorMarketValue = MarketValue.Calculate(accountRow.CurrencyRow, accountRow, sectorRow, MarketValueFlags.EntirePosition | MarketValueFlags.IncludeChildAccounts); // Add the position level target to the model. RemoteMethod insertSector = sectorTargetType.Methods.Add("Insert"); insertSector.Parameters.Add("modelId", insertModel.Parameters["modelId"]); insertSector.Parameters.Add("sectorId", sectorRow.SectorId); insertSector.Parameters.Add("percent", sectorMarketValue / accountMarketValue); } } } } // Save the reference to the 'modelId' return parameter. modelBatch.ModelIdParameter = insertModel.Parameters["modelId"]; // This batch will create a temporary model based on the sector totals of the original account. return(modelBatch); }
/// <summary> /// Creates a temporary model based on the current position level targets. /// </summary> /// <param name="accountRow">An account used as a basis for the targets.</param> /// <param name="schemeRow">The scheme used to select sector targets.</param> /// <returns>A batch of commands that will create a model containing the current position weights of the account.</returns> private static ModelBatch CreatePositionSelfModel(ClientMarketData.AccountRow accountRow, ClientMarketData.SchemeRow schemeRow) { // Create the batch and fill it in with the assembly and type needed for this function. ModelBatch modelBatch = new ModelBatch(); RemoteTransaction remoteTransaction = modelBatch.Transactions.Add(); RemoteAssembly remoteAssembly = modelBatch.Assemblies.Add("Service.Core"); RemoteType remoteType = remoteAssembly.Types.Add("Shadows.WebService.Core.Model"); // Create the temporary, position model based on the scheme used by the original account. RemoteMethod insertModel = remoteType.Methods.Add("Insert"); insertModel.Parameters.Add("modelId", DataType.Int, Direction.ReturnValue); insertModel.Parameters.Add("rowVersion", DataType.Long, Direction.Output); insertModel.Parameters.Add("modelTypeCode", ModelType.Security); insertModel.Parameters.Add("name", "Untitled"); insertModel.Parameters.Add("schemeId", schemeRow.SchemeId); insertModel.Parameters.Add("algorithmId", Algorithm.SecurityRebalancer); insertModel.Parameters.Add("temporary", true); // The 'Self Security' model uses the market value of all the positions, regardless of account or sub-account, when // calculating the denominator for the percentages. decimal accountMarketValue = MarketValue.Calculate(accountRow.CurrencyRow, accountRow, MarketValueFlags.EntirePosition | MarketValueFlags.IncludeChildAccounts); // If the account market value is zero, we can't do much more to create a model. if (accountMarketValue != 0.0M) { // Create a new outline for the model to follow. This will collect the tax lots, proposed orders orders and // allocations into positions that can be used for calculating percentages. Common.Appraisal appraisal = new Common.Appraisal(accountRow, true); // Run through each of the positions, starting with the security. foreach (AppraisalSet.SecurityRow driverSecurity in appraisal.Security) { // This is a position is the destination for the market value calculation. ClientMarketData.SecurityRow securityRow = ClientMarketData.Security.FindBySecurityId(driverSecurity.SecurityId); // The object Type for this operation. RemoteType positionTargetType = remoteAssembly.Types.Add("Shadows.WebService.Core.PositionTarget"); // Run through each of the positions in the appraisal calculating the market value of each position. The ratio // of this market value to the account's market value is the model percentage. foreach (AppraisalSet.PositionRow positionRow in driverSecurity.GetPositionRows()) { // Calculate the market value of the given position. decimal securityMarketValue = MarketValue.Calculate(accountRow.CurrencyRow, accountRow, securityRow, positionRow.PositionTypeCode, MarketValueFlags.EntirePosition | MarketValueFlags.EntirePosition); // Add the position level target to the model. RemoteMethod insertPosition = positionTargetType.Methods.Add("Insert"); insertPosition.Parameters.Add("modelId", insertModel.Parameters["modelId"]); insertPosition.Parameters.Add("securityId", securityRow.SecurityId); insertPosition.Parameters.Add("positionTypeCode", positionRow.PositionTypeCode); insertPosition.Parameters.Add("percent", securityMarketValue / accountMarketValue); } } } // Save the reference to the 'modelId' return parameter. modelBatch.ModelIdParameter = insertModel.Parameters["modelId"]; // This batch will create a temporary model based on the position totals of the original account. return(modelBatch); }