public OrdersElement(BlockOrderDocument blockOrderDocument, ClientMarketData.OrderRow orderRow) : base("Order", blockOrderDocument) { this.orderRow = orderRow; AddAttribute("OrderId", this.orderRow.OrderId); AddAttribute("AccountId", this.orderRow.AccountId); AddAttribute("SecurityId", this.orderRow.SecurityId); AddAttribute("SecurityName", this.orderRow.SecurityRowByFKSecurityOrderSecurityId.ObjectRow.Name); AddAttribute("SecuritySymbol", this.orderRow.SecurityRowByFKSecurityOrderSecurityId.Symbol); AddAttribute("SettlementName", this.orderRow.SecurityRowByFKSecurityOrderSettlementId.ObjectRow.Name); AddAttribute("SettlementSymbol", this.orderRow.SecurityRowByFKSecurityOrderSettlementId.Symbol); AddAttribute("PositionTypeCode", this.orderRow.PositionTypeCode); AddAttribute("TransactionTypeCode", this.orderRow.TransactionTypeCode); AddAttribute("TransactionTypeName", this.orderRow.TransactionTypeRow.Mnemonic); AddAttribute("Quantity", this.orderRow.Quantity); AddAttribute("TimeInForceCode", this.orderRow.TimeInForceCode); AddAttribute("TimeInForceName", this.orderRow.TimeInForceRow.Mnemonic); AddAttribute("OrderTypeCode", this.orderRow.OrderTypeCode); AddAttribute("OrderTypeName", this.orderRow.OrderTypeRow.Mnemonic); ClientMarketData.PriceRow priceRow = ClientMarketData.Price.FindBySecurityIdCurrencyId( this.orderRow.SecurityId, this.orderRow.SettlementId); if (priceRow != null) { AddAttribute("LastPrice", priceRow.LastPrice); AddAttribute("BidPrice", priceRow.BidPrice); AddAttribute("BidSize", priceRow.BidSize); AddAttribute("AskPrice", priceRow.AskPrice); AddAttribute("AskSize", priceRow.AskSize); } if (!this.orderRow.IsPrice1Null()) { AddAttribute("Price1", this.orderRow.Price1); } if (!this.orderRow.IsPrice2Null()) { AddAttribute("Price2", this.orderRow.Price2); } if (!this.orderRow.IsConditionCodeNull()) { AddAttribute("ConditionCode", this.orderRow.ConditionCode); } if (!this.orderRow.IsNoteNull()) { AddAttribute("Note", this.orderRow.Note); } }
/// <summary> /// Finds the price of a security. /// </summary> /// <param name="security">The security.</param> /// <param name="currency">The underlying currency for the price.</param> /// <returns>The price of the security in the specified currency.</returns> public Price(Security security, Security currency) { try { // Lock the tables. Debug.Assert(!ClientMarketData.AreLocksHeld); ClientMarketData.PriceLock.AcquireReaderLock(CommonTimeout.LockWait); // Look up the price record. ClientMarketData.PriceRow priceRow = ClientMarketData.Price.FindBySecurityIdCurrencyId(security.SecurityId, currency.SecurityId); // If we have a record for the price/currency combination, then update it with the new price. if (priceRow != null) { // Initialize the record. this.lastPrice = priceRow.LastPrice; this.lastSize = priceRow.LastSize; this.askPrice = priceRow.AskPrice; this.askSize = priceRow.AskSize; this.bidPrice = priceRow.BidPrice; this.bidSize = priceRow.BidSize; } else { // Initialize the record. this.lastPrice = 0.0M; this.lastSize = 0.0M; this.askPrice = 0.0M; this.askSize = 0.0M; this.bidPrice = 0.0M; this.bidSize = 0.0M; } } finally { // Locks are no longer needed on the price table. if (ClientMarketData.PriceLock.IsReaderLockHeld) { ClientMarketData.PriceLock.ReleaseReaderLock(); } Debug.Assert(!ClientMarketData.AreLocksHeld); } }
public MatchElement(MatchHistoryDocument matchDocument, ClientMarketData.MatchRow matchRow, FieldArray fields) : base("Match", matchDocument) { // WorkingOrderId AddAttribute("MatchId", matchRow.MatchId); AddAttribute("WorkingOrderId", matchRow.WorkingOrderId); AddAttribute("ContraOrderId", matchRow.ContraOrderId); // Status if (fields[Field.Status]) { AddAttribute("StatusCode", matchRow.StatusCode); AddAttribute("StatusName", matchRow.StatusRow.Mnemonic); } // Blotter if (fields[Field.Blotter]) { AddAttribute("Blotter", matchRow.WorkingOrderRow.BlotterRow.BlotterId); AddAttribute("BlotterName", matchRow.WorkingOrderRow.BlotterRow.ObjectRow.Name); } // Security if (fields[Field.Security]) { AddAttribute("SecurityId", matchRow.WorkingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId.SecurityId); AddAttribute("SecuritySymbol", matchRow.WorkingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId.Symbol); AddAttribute("SecurityName", matchRow.WorkingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId.ObjectRow.Name); if (!matchRow.WorkingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId.IsAverageDailyVolumeNull()) { AddAttribute("AverageDailyVolume", matchRow.WorkingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId.AverageDailyVolume / 1000); } if (!matchRow.WorkingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId.IsMarketCapitalizationNull()) { AddAttribute("MarketCapitalization", matchRow.WorkingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId.MarketCapitalization / 1000000); } MemoryStream memoryStream = new MemoryStream(Convert.FromBase64String(matchRow.WorkingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId.Logo)); Bitmap bitmap = new Bitmap(memoryStream); Bitmap halfBitmap = new Bitmap(bitmap, new Size(bitmap.Width / 2, bitmap.Height / 2)); MemoryStream halfStream = new MemoryStream(); halfBitmap.Save(halfStream, System.Drawing.Imaging.ImageFormat.Png); AddAttribute("SecurityImage", Convert.ToBase64String(halfStream.GetBuffer())); } // Submitted Quantity if (fields[Field.SubmittedQuantity]) { AddAttribute("SubmittedQuantity", matchRow.WorkingOrderRow.SubmittedQuantity); } // Quantity Executed if (fields[Field.Execution]) { decimal executedQuantity = decimal.Zero; decimal marketValue = decimal.Zero; foreach (ClientMarketData.NegotiationRow negotiationRow in matchRow.GetNegotiationRows()) { if (negotiationRow.ExecutionRow != null) { executedQuantity = negotiationRow.ExecutionRow.ExecutionQuantity; marketValue = negotiationRow.ExecutionRow.ExecutionPrice * negotiationRow.ExecutionRow.ExecutionQuantity; } } if (executedQuantity != decimal.Zero) { AddAttribute("ExecutedQuantity", executedQuantity); AddAttribute("AveragePrice", marketValue / executedQuantity); } } // Direction (OrderType) if (fields[Field.OrderTypeCode]) { AddAttribute("OrderTypeCode", matchRow.WorkingOrderRow.OrderTypeCode); AddAttribute("OrderTypeMnemonic", matchRow.WorkingOrderRow.OrderTypeRow.Mnemonic); AddAttribute("OrderTypeDescription", matchRow.WorkingOrderRow.OrderTypeRow.Description); } // Created Time. if (fields[Field.CreatedTime]) { AddAttribute("CreatedTime", matchRow.CreatedTime.ToString("s")); } // Find the pricing record. if (!matchRow.WorkingOrderRow.IsSettlementIdNull()) { ClientMarketData.PriceRow priceRow = ClientMarketData.Price.FindBySecurityId(matchRow.WorkingOrderRow.SecurityId); if (priceRow != null) { if (fields[Field.LastPrice]) { AddAttribute("LastPrice", priceRow.LastPrice); } if (fields[Field.BidPrice]) { AddAttribute("BidPrice", priceRow.BidPrice); } if (fields[Field.AskPrice]) { AddAttribute("AskPrice", priceRow.AskPrice); } if (fields[Field.LastSize]) { AddAttribute("LastSize", priceRow.LastSize); } if (fields[Field.BidSize]) { AddAttribute("BidSize", priceRow.BidSize); } if (fields[Field.AskPrice]) { AddAttribute("AskSize", priceRow.AskSize); } if (fields[Field.Volume]) { AddAttribute("Volume", priceRow.Volume); } if (fields[Field.VolumeWeightedAveragePrice]) { AddAttribute("VolumeWeightedAveragePrice", priceRow.VolumeWeightedAveragePrice); } } } }
public DestinationOrderElement(DestinationOrderDocument destinationOrderDocument, ClientMarketData.DestinationOrderRow destinationOrderRow, FieldArray fields) : base("DestinationOrder", destinationOrderDocument) { // Aggregate all the data related to this staged order. This will work out the aggregates and distinct column // operations. if (fields[Field.OrderedQuantity] || fields[Field.ExecutedQuantity]) { AggregateFields(destinationOrderRow); } // DestinationOrderId - Primary Key for this report. AddAttribute("DestinationOrderId", destinationOrderRow.DestinationOrderId); // Status - Note that the status code is always provided to the DOM for color coding of the fields. AddAttribute("StatusCode", destinationOrderRow.StatusCode); if (fields[Field.Status]) { AddAttribute("StatusName", destinationOrderRow.StatusRow.Mnemonic); } // Blotter if (fields[Field.Blotter]) { AddAttribute("Blotter", destinationOrderRow.WorkingOrderRow.BlotterId); AddAttribute("BlotterName", destinationOrderRow.WorkingOrderRow.BlotterRow.ObjectRow.Name); } // OrderType if (fields[Field.OrderType]) { AddAttribute("OrderTypeCode", destinationOrderRow.WorkingOrderRow.OrderTypeCode); AddAttribute("OrderTypeMnemonic", destinationOrderRow.WorkingOrderRow.OrderTypeRow.Mnemonic); AddAttribute("CashSign", destinationOrderRow.WorkingOrderRow.OrderTypeRow.CashSign); AddAttribute("QuantitySign", destinationOrderRow.WorkingOrderRow.OrderTypeRow.QuantitySign); } // TimeInForce if (fields[Field.TimeInForce]) { AddAttribute("TimeInForceCode", destinationOrderRow.WorkingOrderRow.TimeInForceRow.TimeInForceCode); AddAttribute("TimeInForceName", destinationOrderRow.WorkingOrderRow.TimeInForceRow.Mnemonic); } // Security if (fields[Field.Security]) { AddAttribute("SecurityId", destinationOrderRow.WorkingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId.SecurityId); AddAttribute("SecuritySymbol", destinationOrderRow.WorkingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId.Symbol); AddAttribute("SecurityName", destinationOrderRow.WorkingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId.ObjectRow.Name); } // Destination Order Total Quantity if (fields[Field.OrderedQuantity]) { AddAttribute("DestinationOrderQuantity", destinationOrderRow.OrderedQuantity); } // Total Executed Quantity and Average Price if (fields[Field.ExecutedQuantity]) { AddAttribute("ExecutedQuantity", this.totalExecutedQuantity); AddAttribute("AveragePrice", this.averagePriceExecuted); } // Destination Order Leaves (Total Source Quantity - Total Destination Quantity) if (fields[Field.OrderedQuantity] || fields[Field.ExecutedQuantity]) { AddAttribute("LeavesQuantity", this.totalLeavesQuantity); } // Destination if (fields[Field.Destination]) { if (!destinationOrderRow.WorkingOrderRow.IsDestinationIdNull()) { AddAttribute("DestinationId", destinationOrderRow.WorkingOrderRow.DestinationRow.DestinationId); AddAttribute("DestinationName", destinationOrderRow.WorkingOrderRow.DestinationRow.Name); AddAttribute("DestinationShortName", destinationOrderRow.WorkingOrderRow.DestinationRow.ShortName); } } // The Direction of this order (buy, sell, buy cover, etc.) if (fields[Field.PriceType]) { AddAttribute("PriceTypeCode", destinationOrderRow.WorkingOrderRow.PriceTypeRow.PriceTypeCode); AddAttribute("PriceTypeMnemonic", destinationOrderRow.WorkingOrderRow.PriceTypeRow.Mnemonic); } // The remaining Destination Order Fields if (fields[Field.DestinationOrder]) { // Created AddAttribute("CreatedName", destinationOrderRow.WorkingOrderRow.UserRowByUserWorkingOrderCreatedUserId.ObjectRow.Name); AddAttribute("CreatedTime", destinationOrderRow.WorkingOrderRow.CreatedTime.ToString("s")); // Commission AddAttribute("Commission", this.totalCommission); // FilledNet AddAttribute("NetMarketValue", this.totalMarketValue - destinationOrderRow.WorkingOrderRow.OrderTypeRow.CashSign * this.totalCommission); // Market // AddAttribute("MarketId", destinationOrderRow.WorkingOrderRow.SecurityRowByFKSecurityDestinationOrderSecurityId.MarketRow.MarketId); // AddAttribute("MarketName", destinationOrderRow.WorkingOrderRow.SecurityRowByFKSecurityDestinationOrderSecurityId.MarketRow.Name); // AddAttribute("MarketShortName", destinationOrderRow.WorkingOrderRow.SecurityRowByFKSecurityDestinationOrderSecurityId.MarketRow.ShortName); // Limit Price if (!destinationOrderRow.WorkingOrderRow.IsLimitPriceNull()) { AddAttribute("LimitPrice", (decimal)destinationOrderRow.WorkingOrderRow.LimitPrice); } // Stop Price if (!destinationOrderRow.WorkingOrderRow.IsStopPriceNull()) { AddAttribute("StopPrice", (decimal)destinationOrderRow.WorkingOrderRow.StopPrice); } // TradeDate AddAttribute("TradeDate", destinationOrderRow.WorkingOrderRow.CreatedTime.ToString("s")); // CommissionType // if (destinationOrderRow != null) // { // ClientMarketData.CommissionRateTypeRow commissionRateTypeRow = // ClientMarketData.CommissionRateType.FindByCommissionRateTypeCode((int)this.commissionRateTypeCode); // AddAttribute("CommissionRateTypeCode", commissionRateTypeRow.CommissionRateTypeCode); // AddAttribute("CommissionRateTypeName", commissionRateTypeRow.Name); // AddAttribute("CommissionRate", this.averageCommissionRate); // } // Filled Gross AddAttribute("MarketValue", this.totalMarketValue); } // Find the pricing record. if (!destinationOrderRow.WorkingOrderRow.IsSettlementIdNull()) { ClientMarketData.PriceRow priceRow = ClientMarketData.Price.FindBySecurityId(destinationOrderRow.WorkingOrderRow.SecurityId); if (priceRow != null) { if (fields[Field.LastPrice]) { AddAttribute("LastPrice", priceRow.LastPrice); } if (fields[Field.BidPrice]) { AddAttribute("BidPrice", priceRow.BidPrice); } if (fields[Field.AskPrice]) { AddAttribute("AskPrice", priceRow.AskPrice); } if (fields[Field.LastSize]) { AddAttribute("LastSize", priceRow.LastSize); } if (fields[Field.BidSize]) { AddAttribute("BidSize", priceRow.BidSize); } if (fields[Field.AskPrice]) { AddAttribute("AskSize", priceRow.AskSize); } } } }
public QuoteElement(QuoteDocument quoteDocument, ClientMarketData.PriceRow priceRow, FieldArray fields) : base("Quote", quoteDocument) { // try to add the data elements from the security row if (priceRow.SecurityRow != null) { // security name if (fields[Field.SecurityName]) { AddAttribute("SecurityName", priceRow.SecurityRow.ObjectRow.Name); } // symbol if (fields[Field.Symbol]) { AddAttribute("Symbol", priceRow.SecurityRow.Symbol); } } // try to add the data elements from the price row if (priceRow != null) { // SecurityId AddAttribute("SecurityId", priceRow.SecurityId); // last trade if (fields[Field.LastPrice]) { AddAttribute("LastPrice", priceRow.LastPrice); decimal dayPriceDiff = priceRow.LastPrice - priceRow.OpenPrice; AddAttribute("DayPriceDifference", priceRow.LastPrice - priceRow.OpenPrice); AddAttribute("DayPricePercentageDifference", priceRow.OpenPrice == 0.0M ? 0.0M : (priceRow.LastPrice - priceRow.OpenPrice) / priceRow.OpenPrice); } if (fields[Field.PreviousClosePrice]) { AddAttribute("PreviousClosePrice", priceRow.ClosePrice); } if (fields[Field.OpenPrice]) { AddAttribute("OpenPrice", priceRow.OpenPrice); } if (fields[Field.LastSize]) { AddAttribute("LastSize", priceRow.LastSize); } // price if (fields[Field.BidPrice]) { AddAttribute("BidPrice", priceRow.BidPrice); } if (fields[Field.AskPrice]) { AddAttribute("AskPrice", priceRow.AskPrice); } // size if (fields[Field.AskSize]) { AddAttribute("AskSize", priceRow.AskSize); } if (fields[Field.BidSize]) { AddAttribute("BidSize", priceRow.BidSize); } // volume if (fields[Field.Volume]) { AddAttribute("Volume", priceRow.Volume); } if (fields[Field.AverageDailyVolume]) { AddAttribute("AverageDailyVolume", priceRow.SecurityRow.AverageDailyVolume); } if (fields[Field.DayLowPrice]) { AddAttribute("DayLowPrice", priceRow.LowPrice); } if (fields[Field.DayHighPrice]) { AddAttribute("DayHighPrice", priceRow.HighPrice); } /* LOGO ??? * MemoryStream memoryStream = new MemoryStream(Convert.FromBase64String(matchRow.WorkingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId.Logo)); * Bitmap bitmap = new Bitmap(memoryStream); * Bitmap halfBitmap = new Bitmap(bitmap, new Size(bitmap.Width / 2, bitmap.Height / 2)); * MemoryStream halfStream = new MemoryStream(); * halfBitmap.Save(halfStream, System.Drawing.Imaging.ImageFormat.Png); * AddAttribute("SecurityImage", Convert.ToBase64String(halfStream.GetBuffer())); * */ } }
/// <summary> /// Creates a well formed quote document object model from fragments of data. /// </summary> /// <param name="fragmentList">A collection of fragments to be added/removed from the document in the viewer.</param> public QuoteDocument(FragmentList fragmentList) { try { // Lock the tables System.Diagnostics.Debug.Assert(!ClientMarketData.IsLocked); ClientMarketData.BlotterLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.SourceOrderLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.DestinationLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.DestinationOrderLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.ExecutionLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.ImageLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.ObjectLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.ObjectTreeLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.OrderTypeLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.PriceTypeLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.PriceLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.SecurityLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.StatusLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.StylesheetLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.TimeInForceLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.TimerLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.UserLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.WorkingOrderLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.VolumeCategoryLock.AcquireReaderLock(CommonTimeout.LockWait); // The root of the fragment document. XmlNode fragmentNode = this.AppendChild(this.CreateElement("Fragment")); // The insert, update and delete elements are only included only when there is data in those sections. XmlNode insertNode = null; XmlNode updateNode = null; XmlNode deleteNode = null; foreach (Fragment fragment in fragmentList) { // The generic record in the fragment is cast here to a WorkingOrderRow. By design, this is the only type of // record that will be placed into the FragmentList. ClientMarketData.PriceRow priceRow = (ClientMarketData.PriceRow)fragment.Row; // Insert, Update or Delete the fragment. switch (fragment.DataAction) { case DataAction.Insert: // The 'insert' element is optional until there is something to insert. if (insertNode == null) { insertNode = fragmentNode.AppendChild(this.CreateElement("Insert")); } // Insert the record. insertNode.AppendChild(new QuoteElement(this, priceRow, FieldArray.Set)); break; case DataAction.Update: // The 'update' element is optional until there is something to update. if (updateNode == null) { updateNode = fragmentNode.AppendChild(this.CreateElement("Update")); } // Update individual properties of the record. updateNode.AppendChild(new QuoteElement(this, priceRow, fragment.Fields)); break; case DataAction.Delete: // The 'delete' element is optional until there is something to delete. if (deleteNode == null) { deleteNode = fragmentNode.AppendChild(this.CreateElement("Delete")); } // The original record can't be used (because it has been deleted, duh). A key is constructed from the data // stored in the fragment list. CommonElement commonElement = new CommonElement("QuoteOrder", this); commonElement.AddAttribute("SecurityId", (int)fragment.Key[0]); deleteNode.AppendChild(commonElement); break; } } } catch (Exception exception) { // Write the error and stack trace out to the event log. EventLog.Error("{0}, {1}", exception.Message, exception.StackTrace); } finally { // Release the table locks. if (ClientMarketData.BlotterLock.IsReaderLockHeld) { ClientMarketData.BlotterLock.ReleaseReaderLock(); } if (ClientMarketData.SourceOrderLock.IsReaderLockHeld) { ClientMarketData.SourceOrderLock.ReleaseReaderLock(); } if (ClientMarketData.DestinationLock.IsReaderLockHeld) { ClientMarketData.DestinationLock.ReleaseReaderLock(); } if (ClientMarketData.DestinationOrderLock.IsReaderLockHeld) { ClientMarketData.DestinationOrderLock.ReleaseReaderLock(); } if (ClientMarketData.ExecutionLock.IsReaderLockHeld) { ClientMarketData.ExecutionLock.ReleaseReaderLock(); } if (ClientMarketData.ImageLock.IsReaderLockHeld) { ClientMarketData.ImageLock.ReleaseReaderLock(); } if (ClientMarketData.ObjectLock.IsReaderLockHeld) { ClientMarketData.ObjectLock.ReleaseReaderLock(); } if (ClientMarketData.ObjectTreeLock.IsReaderLockHeld) { ClientMarketData.ObjectTreeLock.ReleaseReaderLock(); } if (ClientMarketData.OrderTypeLock.IsReaderLockHeld) { ClientMarketData.OrderTypeLock.ReleaseReaderLock(); } if (ClientMarketData.PriceTypeLock.IsReaderLockHeld) { ClientMarketData.PriceTypeLock.ReleaseReaderLock(); } if (ClientMarketData.PriceLock.IsReaderLockHeld) { ClientMarketData.PriceLock.ReleaseReaderLock(); } if (ClientMarketData.SecurityLock.IsReaderLockHeld) { ClientMarketData.SecurityLock.ReleaseReaderLock(); } if (ClientMarketData.StatusLock.IsReaderLockHeld) { ClientMarketData.StatusLock.ReleaseReaderLock(); } if (ClientMarketData.StylesheetLock.IsReaderLockHeld) { ClientMarketData.StylesheetLock.ReleaseReaderLock(); } if (ClientMarketData.TimeInForceLock.IsReaderLockHeld) { ClientMarketData.TimeInForceLock.ReleaseReaderLock(); } if (ClientMarketData.TimerLock.IsReaderLockHeld) { ClientMarketData.TimerLock.ReleaseReaderLock(); } if (ClientMarketData.UserLock.IsReaderLockHeld) { ClientMarketData.UserLock.ReleaseReaderLock(); } if (ClientMarketData.WorkingOrderLock.IsReaderLockHeld) { ClientMarketData.WorkingOrderLock.ReleaseReaderLock(); } if (ClientMarketData.VolumeCategoryLock.IsReaderLockHeld) { ClientMarketData.VolumeCategoryLock.ReleaseReaderLock(); } System.Diagnostics.Debug.Assert(!ClientMarketData.IsLocked); } }
/// <summary> /// This handler is called when prices have changed. /// </summary> /// <param name="sender">The object that originated the event.</param> /// <param name="priceRowChangingEvent">Event argument.</param> private void ChangePriceRow(object sender, ClientMarketData.PriceRowChangeEvent priceRowChangeEvent) { if (priceRowChangeEvent.Action == DataRowAction.Commit) { // Extract the price row from the event argumetns. ClientMarketData.PriceRow priceRow = priceRowChangeEvent.Row; // The code below will compare the current values to the original ones and set an indicator for which values have // changed. This set of indicators will determine which values are included in the incremental XML fragment that // is created to update the viewer. FieldArray fields = FieldArray.Set; //FieldArray.Set; // There will only be 'Current' rows after the first batch of data is read from the server into the data model. // This check is needed to prevent exceptions when comparing the current row to the original one. if (!priceRow.HasVersion(DataRowVersion.Original)) { return; } // don't perform update if the securityId is not the security being displayed if (!priceRow.SecurityId.Equals(this.Tag)) { return; } // Set an indicator if the Last Price has changed. if (!priceRow[ClientMarketData.Price.LastPriceColumn, DataRowVersion.Original].Equals( priceRow[ClientMarketData.Price.LastPriceColumn, DataRowVersion.Current])) { fields[Field.LastPrice] = true; } // Set an indicator if the Ask Price has changed. if (!priceRow[ClientMarketData.Price.AskPriceColumn, DataRowVersion.Original].Equals( priceRow[ClientMarketData.Price.AskPriceColumn, DataRowVersion.Current])) { fields[Field.AskPrice] = true; } // Set an indicator if the Bid Price has changed. if (!priceRow[ClientMarketData.Price.BidPriceColumn, DataRowVersion.Original].Equals( priceRow[ClientMarketData.Price.BidPriceColumn, DataRowVersion.Current])) { fields[Field.BidPrice] = true; } // Set an indicator if the Last Size has changed. if (!priceRow[ClientMarketData.Price.LastSizeColumn, DataRowVersion.Original].Equals( priceRow[ClientMarketData.Price.LastSizeColumn, DataRowVersion.Current])) { fields[Field.LastSize] = true; } // Set an indicator if the Ask Size has changed. if (!priceRow[ClientMarketData.Price.AskSizeColumn, DataRowVersion.Original].Equals( priceRow[ClientMarketData.Price.AskSizeColumn, DataRowVersion.Current])) { fields[Field.AskSize] = true; } // Set an indicator if the Bid Size has changed. if (!priceRow[ClientMarketData.Price.BidSizeColumn, DataRowVersion.Original].Equals( priceRow[ClientMarketData.Price.BidSizeColumn, DataRowVersion.Current])) { fields[Field.BidSize] = true; } // Set an indiator if the Volume has changed. if (!priceRow[ClientMarketData.Price.VolumeColumn, DataRowVersion.Original].Equals( priceRow[ClientMarketData.Price.VolumeColumn, DataRowVersion.Current])) { fields[Field.Volume] = true; } if (fields) { this.fragmentList.Add(DataAction.Update, priceRow, fields); } } }
public MatchElement(MatchDocument matchDocument, ClientMarketData.MatchRow matchRow, FieldArray fields) : base("Match", matchDocument) { // WorkingOrderId AddAttribute("MatchId", matchRow.MatchId); AddAttribute("WorkingOrderId", matchRow.WorkingOrderId); AddAttribute("ContraOrderId", matchRow.ContraOrderId); // Status if (fields[Field.Status]) { AddAttribute("StatusCode", matchRow.StatusCode); AddAttribute("StatusName", matchRow.StatusRow.Mnemonic); TimeSpan timeLeft = matchRow.TimerRow.StopTime.Subtract(matchRow.TimerRow.CurrentTime); AddAttribute("TimeLeft", string.Format("{0:0}:{1:00}", timeLeft.Minutes, timeLeft.Seconds)); AddAttribute("SecondsLeft", Convert.ToInt32(timeLeft.TotalSeconds)); } // Blotter if (fields[Field.Blotter]) { AddAttribute("Blotter", matchRow.WorkingOrderRow.BlotterRow.BlotterId); AddAttribute("BlotterName", matchRow.WorkingOrderRow.BlotterRow.ObjectRow.Name); } // Security if (fields[Field.Security]) { AddAttribute("SecurityId", matchRow.WorkingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId.SecurityId); AddAttribute("SecuritySymbol", matchRow.WorkingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId.Symbol); AddAttribute("SecurityName", matchRow.WorkingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId.ObjectRow.Name); if (!matchRow.WorkingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId.IsAverageDailyVolumeNull()) { AddAttribute("AverageDailyVolume", matchRow.WorkingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId.AverageDailyVolume / 1000); } if (!matchRow.WorkingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId.IsMarketCapitalizationNull()) { AddAttribute("MarketCapitalization", matchRow.WorkingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId.MarketCapitalization / 1000000); } AddAttribute("VolumeCategoryMnemonic", matchRow.WorkingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId.VolumeCategoryRow.Mnemonic); MemoryStream memoryStream = new MemoryStream(Convert.FromBase64String(matchRow.WorkingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId.Logo)); Bitmap bitmap = new Bitmap(memoryStream); Bitmap halfBitmap = new Bitmap(bitmap, new Size(bitmap.Width / 2, bitmap.Height / 2)); MemoryStream halfStream = new MemoryStream(); halfBitmap.Save(halfStream, System.Drawing.Imaging.ImageFormat.Png); AddAttribute("SecurityImage", Convert.ToBase64String(halfStream.GetBuffer())); } // Submitted Quantity if (fields[Field.SubmittedQuantity]) { AddAttribute("SubmittedQuantity", matchRow.WorkingOrderRow.SubmittedQuantity); } // Direction (OrderType) if (fields[Field.OrderTypeCode]) { AddAttribute("OrderTypeCode", matchRow.WorkingOrderRow.OrderTypeCode); AddAttribute("OrderTypeMnemonic", matchRow.WorkingOrderRow.OrderTypeRow.Mnemonic); } // Find the pricing record. if (!matchRow.WorkingOrderRow.IsSettlementIdNull()) { ClientMarketData.PriceRow priceRow = ClientMarketData.Price.FindBySecurityId(matchRow.WorkingOrderRow.SecurityId); if (priceRow != null) { if (fields[Field.LastPrice]) { AddAttribute("LastPrice", priceRow.LastPrice); } if (fields[Field.BidPrice]) { AddAttribute("BidPrice", priceRow.BidPrice); } if (fields[Field.AskPrice]) { AddAttribute("AskPrice", priceRow.AskPrice); } if (fields[Field.LastSize]) { AddAttribute("LastSize", priceRow.LastSize); } if (fields[Field.BidSize]) { AddAttribute("BidSize", priceRow.BidSize); } if (fields[Field.AskPrice]) { AddAttribute("AskSize", priceRow.AskSize); } if (fields[Field.Volume]) { AddAttribute("Volume", priceRow.Volume); } if (fields[Field.InterpolatedVolume]) { AddAttribute("InterpolatedVolume", VolumeHelper.CurrentVolumePercentage(DateTime.Now, matchRow.WorkingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId.AverageDailyVolume, priceRow.Volume)); } if (fields[Field.VolumeWeightedAveragePrice]) { AddAttribute("VolumeWeightedAveragePrice", priceRow.VolumeWeightedAveragePrice); } } } }
/// <summary> /// Creates an Equity Element for an Appriasal Document. /// </summary> /// <param name="appraisalDocument">The parent Xml Document.</param> /// <param name="equityRow">An equity record from the data model.</param> /// <param name="PositionTypeCode">Whether a short or long position.</param> public EquityElement(AppraisalDocument appraisalDocument, ClientMarketData.EquityRow equityRow, AppraisalSet.PositionRow positionRow) : base("Equity", appraisalDocument) { // These records are used to access information held in the ancestors. ClientMarketData.SecurityRow securityRow = equityRow.SecurityRowByFKSecurityEquityEquityId; ClientMarketData.ObjectRow objectRow = securityRow.ObjectRow; // Add the essential attributes for this element. AddAttribute("SecurityId", equityRow.EquityId.ToString()); AddAttribute("PositionTypeCode", positionRow.PositionTypeCode.ToString()); AddAttribute("Name", objectRow.Name.ToString()); AddAttribute("PriceFactor", securityRow.PriceFactor.ToString()); AddAttribute("QuantityFactor", securityRow.QuantityFactor.ToString()); // Find the price based on the default currency found in the equity record. If the security master doesn't // have a price for this security, provide dummy values to insure a market value can be calculated. Zero is a // perfectly reasonable interpretation of a missing price. ClientMarketData.PriceRow securityPrice = ClientMarketData.Price.FindBySecurityIdCurrencyId( securityRow.SecurityId, equityRow.SettlementId); if (securityPrice == null) { AddAttribute("Price", "0.0"); } else { if (ClientPreferences.Pricing == Pricing.Close) { AddAttribute("Price", securityPrice.ClosePrice.ToString()); } if (ClientPreferences.Pricing == Pricing.Last) { AddAttribute("Price", securityPrice.LastPrice.ToString()); } } // Find the crossing price. This is used to convert any local price into the account's base currency. Provide // defaults if the crossing price can be found. While this will lead to wrong values, they will be obvious on // the appraisal. ClientMarketData.PriceRow currencyPrice = ClientMarketData.Price.FindBySecurityIdCurrencyId( equityRow.SettlementId, appraisalDocument.AccountRow.CurrencyRow.CurrencyId); if (currencyPrice == null) { AddAttribute("CloseCrossPrice", "0.0"); AddAttribute("LastCrossPrice", "0.0"); } else { AddAttribute("CloseCrossPrice", currencyPrice.ClosePrice.ToString()); AddAttribute("LastCrossPrice", currencyPrice.LastPrice.ToString()); } // Add a target percentage if one is associated with this security. ClientMarketData.PositionTargetRow positionTargetRow = ClientMarketData.PositionTarget.FindByModelIdSecurityIdPositionTypeCode( appraisalDocument.ModelRow.ModelId, equityRow.EquityId, positionRow.PositionTypeCode); if (positionTargetRow != null) { AddAttribute("ModelPercent", positionTargetRow.Percent.ToString()); } // If there is a position record associated with this, er.. position, then add the externally supplied data // to the record. Since the tax lots are always aggregated as we need them into a position, there's no static // table that keeps position data. This information is generally from an outside system that is related to // the position, such as risk metrics or quantitative calculations. ClientMarketData.PositionRow position = ClientMarketData.Position.FindByAccountIdSecurityIdPositionTypeCode( appraisalDocument.AccountRow.AccountId, positionRow.SecurityId, positionRow.PositionTypeCode); if (position != null) { if (!position.IsUserData0Null()) { AddAttribute("UserData0", position.UserData0.ToString()); } if (!position.IsUserData1Null()) { AddAttribute("UserData1", position.UserData1.ToString()); } if (!position.IsUserData2Null()) { AddAttribute("UserData2", position.UserData2.ToString()); } if (!position.IsUserData3Null()) { AddAttribute("UserData3", position.UserData3.ToString()); } if (!position.IsUserData4Null()) { AddAttribute("UserData4", position.UserData4.ToString()); } if (!position.IsUserData5Null()) { AddAttribute("UserData5", position.UserData5.ToString()); } if (!position.IsUserData6Null()) { AddAttribute("UserData6", position.UserData6.ToString()); } if (!position.IsUserData7Null()) { AddAttribute("UserData7", position.UserData7.ToString()); } } // Add the account level aggregates for this security/position type pair. foreach (AppraisalSet.AccountRow accountRow in positionRow.GetAccountRows()) { this.AppendChild(new AccountElement(appraisalDocument, accountRow)); } }
/// <summary> /// Creates a Currency Element for an Appraisal Document. /// </summary> /// <param name="appraisalDocument">The parent Xml Document.</param> /// <param name="currencyRow">A currency record in the data model.</param> /// <param name="PositionTypeCode">Whether a short or long position.</param> public CurrencyElement(AppraisalDocument appraisalDocument, ClientMarketData.CurrencyRow currencyRow, AppraisalSet.PositionRow positionRow) : base("Currency", appraisalDocument) { // These records are used to access information held in the ancestors. ClientMarketData.SecurityRow securityRow = currencyRow.SecurityRow; ClientMarketData.ObjectRow objectRow = securityRow.ObjectRow; // Add the essential attributes for this element. AddAttribute("SecurityId", currencyRow.CurrencyId.ToString()); AddAttribute("PositionTypeCode", positionRow.PositionTypeCode.ToString()); AddAttribute("Name", objectRow.Name.ToString()); // Add the price info. ClientMarketData.PriceRow priceRow = ClientMarketData.Price.FindBySecurityIdCurrencyId(securityRow.SecurityId, appraisalDocument.AccountRow.CurrencyRow.CurrencyId); if (priceRow == null) { AddAttribute("Price", "0.0"); } else { if (ClientPreferences.Pricing == Pricing.Close) { AddAttribute("Price", priceRow.ClosePrice.ToString()); } if (ClientPreferences.Pricing == Pricing.Last) { AddAttribute("Price", priceRow.LastPrice.ToString()); } } // Add a target percentage if one is associated with this security. ClientMarketData.PositionTargetRow positionTargetRow = ClientMarketData.PositionTarget.FindByModelIdSecurityIdPositionTypeCode( appraisalDocument.ModelRow.ModelId, currencyRow.CurrencyId, positionRow.PositionTypeCode); if (positionTargetRow != null) { AddAttribute("ModelPercent", positionTargetRow.Percent.ToString()); } // If there is a position record associated with this, er.. position, then add the externally supplied data // to the record. Since the tax lots are always aggregated as we need them into a position, there's no static // table that keeps position data. This information is generally from an outside system that is related to // the position, such as risk metrics or quantitative calculations. ClientMarketData.PositionRow position = ClientMarketData.Position.FindByAccountIdSecurityIdPositionTypeCode( appraisalDocument.AccountRow.AccountId, positionRow.SecurityId, positionRow.PositionTypeCode); if (position != null) { if (!position.IsUserData0Null()) { AddAttribute("UserData0", position.UserData0.ToString()); } if (!position.IsUserData1Null()) { AddAttribute("UserData1", position.UserData1.ToString()); } if (!position.IsUserData2Null()) { AddAttribute("UserData2", position.UserData2.ToString()); } if (!position.IsUserData3Null()) { AddAttribute("UserData3", position.UserData3.ToString()); } if (!position.IsUserData4Null()) { AddAttribute("UserData4", position.UserData4.ToString()); } if (!position.IsUserData5Null()) { AddAttribute("UserData5", position.UserData5.ToString()); } if (!position.IsUserData6Null()) { AddAttribute("UserData6", position.UserData6.ToString()); } if (!position.IsUserData7Null()) { AddAttribute("UserData7", position.UserData7.ToString()); } } // Append the account level aggregates to this security/position type element. foreach (AppraisalSet.AccountRow accountRow in positionRow.GetAccountRows()) { this.AppendChild(new AccountElement(appraisalDocument, accountRow)); } }
public void CalculateFields() { // The block order document has an operation that displays distinct values when the occur. For instance, if // all the orders in the block have the same time in force, then that time in force will appear in the // document at the block level. However, if any one of the elements is different from the others, the same // column would be blanked out to show that there is more than one value associated with this attribute of the // block. The first order is used as a seed for this operation. If any element in the block doesn't share // the first order's attribute, then that attribute is left blank. decimal quantityOrdered = 0.0M; OrdersElement firstOrder = (OrdersElement)this.SelectSingleNode(".//Order"); if (firstOrder != null) { // Aggregates by Orders. int orders = 0; int securityIdSum = 0; int accountIdSum = 0; int transactionTypeCodeSum = 0; int timeInForceCodeSum = 0; int orderTypeCodeSum = 0; decimal price1Sum = 0.0M; decimal price2Sum = 0.0M; foreach (OrdersElement ordersElement in this.SelectNodes("Order")) { orders++; securityIdSum += ordersElement.OrderRow.SecurityId; accountIdSum += ordersElement.OrderRow.AccountId; transactionTypeCodeSum += ordersElement.OrderRow.TransactionTypeCode; timeInForceCodeSum += ordersElement.OrderRow.TimeInForceCode; orderTypeCodeSum += ordersElement.OrderRow.OrderTypeCode; price1Sum += ordersElement.OrderRow.IsPrice1Null() ? 0.0M : ordersElement.OrderRow.Price1; price2Sum += ordersElement.OrderRow.IsPrice2Null() ? 0.0M : ordersElement.OrderRow.Price2; quantityOrdered += ordersElement.OrderRow.Quantity; } if (securityIdSum == firstOrder.OrderRow.SecurityId * orders) { AddAttribute("SecurityId", firstOrder.OrderRow.SecurityId); ClientMarketData.SecurityRow securityRow = firstOrder.OrderRow.SecurityRowByFKSecurityOrderSecurityId; AddAttribute("SecurityName", securityRow.ObjectRow.Name); AddAttribute("SecuritySymbol", securityRow.Symbol); ClientMarketData.PriceRow priceRow = ClientMarketData.Price.FindBySecurityIdCurrencyId( firstOrder.OrderRow.SecurityId, firstOrder.OrderRow.SettlementId); if (priceRow != null) { AddAttribute("LastPrice", priceRow.LastPrice); AddAttribute("BidPrice", priceRow.BidPrice); AddAttribute("BidSize", priceRow.BidSize); AddAttribute("AskPrice", priceRow.AskPrice); AddAttribute("AskSize", priceRow.AskSize); } // Add Fixed Income Fundamentals where they exist. foreach (ClientMarketData.DebtRow debtRow in securityRow.GetDebtRowsByFKSecurityDebtDebtId()) { if (!debtRow.IsIssuerIdNull()) { AddAttribute("IssuerId", debtRow.IssuerId); } AddAttribute("DebtTypeCode", debtRow.DebtTypeCode); AddAttribute("Coupon", debtRow.Coupon); AddAttribute("MaturityDate", debtRow.MaturityDate.ToShortDateString()); } } if (accountIdSum == firstOrder.OrderRow.AccountId * orders) { AddAttribute("AccountId", firstOrder.OrderRow.AccountId); ClientMarketData.AccountRow accountRow = firstOrder.OrderRow.AccountRow; AddAttribute("AccountName", accountRow.ObjectRow.Name); } if (transactionTypeCodeSum == firstOrder.OrderRow.TransactionTypeCode * orders) { AddAttribute("TransactionTypeCode", firstOrder.OrderRow.TransactionTypeCode); AddAttribute("TransactionTypeName", firstOrder.OrderRow.TransactionTypeRow.Mnemonic); } if (timeInForceCodeSum == firstOrder.OrderRow.TimeInForceCode * orders) { AddAttribute("TimeInForceCode", firstOrder.OrderRow.TimeInForceCode); AddAttribute("TimeInForceName", firstOrder.OrderRow.TimeInForceRow.Mnemonic); } if (orderTypeCodeSum == firstOrder.OrderRow.OrderTypeCode * orders) { AddAttribute("OrderTypeCode", firstOrder.OrderRow.OrderTypeCode); AddAttribute("OrderTypeName", firstOrder.OrderRow.OrderTypeRow.Mnemonic); } if (!firstOrder.OrderRow.IsPrice1Null() && price1Sum == firstOrder.OrderRow.Price1 * orders) { AddAttribute("Price1", firstOrder.OrderRow.Price1); } if (!firstOrder.OrderRow.IsPrice2Null() && price2Sum == firstOrder.OrderRow.Price2 * orders) { AddAttribute("Price2", firstOrder.OrderRow.Price2); } // HACK - Trade and Settlement are defaulted. These should be distinct elements from the executions. AddAttribute("TradeDate", DateTime.Now.ToShortDateString()); AddAttribute("SettlementDate", DateTime.Now.ToShortDateString()); } AddAttribute("QuantityOrdered", quantityOrdered); // Aggregate Placements decimal quantityPlaced = 0.0M; PlacementsElement firstPlacement = (PlacementsElement)this.SelectSingleNode(".//Placement"); if (firstPlacement != null) { // Aggregates by Placements. int placements = 0; int brokerIdSum = 0; foreach (PlacementsElement placementsElement in this.SelectNodes("Placement")) { placements++; brokerIdSum += placementsElement.PlacementRow.BrokerId; quantityPlaced += placementsElement.PlacementRow.Quantity; } if (brokerIdSum == firstPlacement.PlacementRow.BrokerId * placements) { AddAttribute("PlacementBrokerId", firstPlacement.PlacementRow.BrokerId); AddAttribute("PlacementBrokerSymbol", firstPlacement.PlacementRow.BrokerRow.Symbol); } } AddAttribute("QuantityPlaced", quantityPlaced); // Aggregate Execution decimal quantityExecuted = 0.0M; ExecutionElement firstExecution = (ExecutionElement)this.SelectSingleNode(".//Execution"); if (firstExecution != null) { // Aggregates by Execution. int placements = 0; int brokerIdSum = 0; foreach (ExecutionElement placementsElement in this.SelectNodes("Execution")) { placements++; brokerIdSum += placementsElement.ExecutionRow.BrokerId; quantityExecuted += placementsElement.ExecutionRow.Quantity; } if (brokerIdSum == firstExecution.ExecutionRow.BrokerId * placements) { AddAttribute("PlacementBrokerId", firstExecution.ExecutionRow.BrokerId); AddAttribute("PlacementBrokerSymbol", firstExecution.ExecutionRow.BrokerRow.Symbol); } } AddAttribute("QuantityExecuted", quantityExecuted); }
/// <summary> /// Opens the document for the given object and it's argument. /// </summary> /// <param name="matchId">The primary identifier of the object to open.</param> /// <param name="argument">Options that can be used to further specify the document's properties.</param> public void OpenMatchCommand(object parameter) { // Extract the command argument. int matchId = (int)parameter; // This will force an empty placement and placement document to appear until we get some data. It's the same // as forcing a drawing of the headers only. this.matchId = matchId; try { // Lock the tables System.Diagnostics.Debug.Assert(!ClientMarketData.IsLocked); ClientMarketData.EquityLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.MatchLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.ObjectLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.PriceLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.SecurityLock.AcquireReaderLock(CommonTimeout.LockWait); ClientMarketData.WorkingOrderLock.AcquireReaderLock(CommonTimeout.LockWait); // Install the event handlers. The ClientMarketData component will advise us when the data has changed. ClientMarketData.MatchRow matchRow = ClientMarketData.Match.FindByMatchId(matchId); if (matchRow == null) { return; } ClientMarketData.SecurityRow securityRow = matchRow.WorkingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId; ClientMarketData.EquityRow equityRow = ClientMarketData.Equity.FindByEquityId(securityRow.SecurityId); if (equityRow == null) { return; } string securityName = securityRow.ObjectRow.Name; ClientMarketData.PriceRow priceRow = ClientMarketData.Price.FindBySecurityId(securityRow.SecurityId); decimal price = priceRow.LastPrice; Invoke(displayDelegate, new object[] { securityName, price }); } finally { if (ClientMarketData.EquityLock.IsReaderLockHeld) { ClientMarketData.EquityLock.ReleaseReaderLock(); } if (ClientMarketData.MatchLock.IsReaderLockHeld) { ClientMarketData.MatchLock.ReleaseReaderLock(); } if (ClientMarketData.ObjectLock.IsReaderLockHeld) { ClientMarketData.ObjectLock.ReleaseReaderLock(); } if (ClientMarketData.PriceLock.IsReaderLockHeld) { ClientMarketData.PriceLock.ReleaseReaderLock(); } if (ClientMarketData.SecurityLock.IsReaderLockHeld) { ClientMarketData.SecurityLock.ReleaseReaderLock(); } if (ClientMarketData.WorkingOrderLock.IsReaderLockHeld) { ClientMarketData.WorkingOrderLock.ReleaseReaderLock(); } System.Diagnostics.Debug.Assert(!ClientMarketData.IsLocked); } }
public WorkingOrderElement(WorkingOrderDocument workingOrderDocument, ClientMarketData.WorkingOrderRow workingOrderRow, FieldArray fields) : base("WorkingOrder", workingOrderDocument) { // Aggregate all the data related to this staged order. This will work out the aggregates and distinct column // operations. if (fields[Field.SourceOrder] || fields[Field.DestinationOrder] || fields[Field.Execution] || fields[Field.Allocation]) { AggregateFields(workingOrderRow); } // WorkingOrderId - Primary Key for this report. AddAttribute("WorkingOrderId", workingOrderRow.WorkingOrderId); // Status - Note that the status code is always provided to the DOM for color coding of the fields. AddAttribute("StatusCode", workingOrderRow.StatusCode); if (fields[Field.Status]) { AddAttribute("StatusName", workingOrderRow.StatusRow.Mnemonic); } // Select a green flag for submitted records, a red flag for unsubmitted. int imageIndex = -1; switch (workingOrderRow.StatusCode) { case Status.Error: imageIndex = ClientMarketData.Image.KeyImageExternalId0.Find("Error Small"); break; case Status.Submitted: imageIndex = ClientMarketData.Image.KeyImageExternalId0.Find("Flag Green Small"); break; default: imageIndex = ClientMarketData.Image.KeyImageExternalId0.Find("Flag Red Small"); break; } if (imageIndex != -1) { ClientMarketData.ImageRow imageRow = (ClientMarketData.ImageRow)ClientMarketData.Image.KeyImageExternalId0[imageIndex].Row; AddAttribute("StatusImage", imageRow.Image); } // Blotter if (fields[Field.Blotter]) { AddAttribute("Blotter", workingOrderRow.BlotterId); AddAttribute("BlotterName", workingOrderRow.BlotterRow.ObjectRow.Name); } // SubmissionTypeCode if (fields[Field.SubmissionTypeCode]) { AddAttribute("SubmissionTypeCode", workingOrderRow.SubmissionTypeCode); } // IsBrokerMatch if (fields[Field.IsBrokerMatch]) { AddAttribute("IsBrokerMatch", workingOrderRow.IsBrokerMatch); } // IsInstitutionMatch if (fields[Field.IsInstitutionMatch]) { AddAttribute("IsInstitutionMatch", workingOrderRow.IsInstitutionMatch); } // IsHedgeMatch if (fields[Field.IsHedgeMatch]) { AddAttribute("IsHedgeMatch", workingOrderRow.IsHedgeMatch); } // Auto-Execute - we always send the isAutomatic flag and the quantity if (fields[Field.AutoExecute]) { AddAttribute("IsAutomatic", workingOrderRow.IsAutomatic); if (!workingOrderRow.IsAutomaticQuantityNull()) { AddAttribute("AutomaticQuantity", workingOrderRow.AutomaticQuantity); } else { AddAttribute("AutomaticQuantity", 0); } } // LimitPrice if (fields[Field.LimitPrice]) { if (!workingOrderRow.IsLimitPriceNull()) { AddAttribute("LimitPrice", workingOrderRow.LimitPrice); } else { AddAttribute("LimitPrice", 0); } } // OrderType if (fields[Field.OrderType]) { AddAttribute("OrderTypeCode", workingOrderRow.OrderTypeCode); AddAttribute("OrderTypeDescription", workingOrderRow.OrderTypeRow.Description); AddAttribute("OrderTypeMnemonic", workingOrderRow.OrderTypeRow.Mnemonic); AddAttribute("CashSign", workingOrderRow.OrderTypeRow.CashSign); AddAttribute("QuantitySign", workingOrderRow.OrderTypeRow.QuantitySign); // Select a green flag for submitted records, a red flag for unsubmitted. int orderTypeImageIndex = -1; switch (workingOrderRow.OrderTypeCode) { case OrderType.Buy: orderTypeImageIndex = ClientMarketData.Image.KeyImageExternalId0.Find("Navigate Plain Green Small"); break; case OrderType.Sell: orderTypeImageIndex = ClientMarketData.Image.KeyImageExternalId0.Find("Navigate Plain Red Small"); break; } if (orderTypeImageIndex != -1) { ClientMarketData.ImageRow imageRow = (ClientMarketData.ImageRow)ClientMarketData.Image.KeyImageExternalId0[orderTypeImageIndex].Row; AddAttribute("OrderTypeImage", imageRow.Image); } } // TimeInForce if (fields[Field.TimeInForce]) { AddAttribute("TimeInForceCode", workingOrderRow.TimeInForceRow.TimeInForceCode); AddAttribute("TimeInForceName", workingOrderRow.TimeInForceRow.Mnemonic); } // Security if (fields[Field.Security]) { AddAttribute("SecurityId", workingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId.SecurityId); AddAttribute("SecuritySymbol", workingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId.Symbol); AddAttribute("SecurityName", workingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId.ObjectRow.Name); if (!workingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId.IsMarketCapitalizationNull()) { AddAttribute("MarketCapitalization", workingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId.MarketCapitalization / 1000000.0m); } if (!workingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId.IsAverageDailyVolumeNull()) { AddAttribute("AverageDailyVolume", workingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId.AverageDailyVolume / 1000.0m); } AddAttribute("VolumeCategoryMnemonic", workingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId.VolumeCategoryRow.Mnemonic); } // Source Order Total Quantity if (fields[Field.SourceOrder]) { AddAttribute("SourceOrderQuantity", this.totalSourceOrderedQuantity); } // Destination Order Total Quantity if (fields[Field.DestinationOrder]) { AddAttribute("DestinationOrderQuantity", this.totalDestinationOrderedQuantity); } // Total Executed Quantity and Average Price if (fields[Field.SubmittedQuantity]) { AddAttribute("SubmittedQuantity", workingOrderRow.SubmittedQuantity); } // Total Executed Quantity and Average Price if (fields[Field.Execution]) { AddAttribute("ExecutedQuantity", this.totalExecutedQuantity); AddAttribute("AveragePrice", this.averagePriceExecuted); } // Total Quantity Allocated if (fields[Field.Allocation]) { AddAttribute("AllocatedQuantity", this.totalAllocatedQuantity); } // Working Order Leaves (Total Source Quantity - Total Destination Quantity) if (fields[Field.SourceOrder] || fields[Field.DestinationOrder]) { AddAttribute("LeavesQuantity", this.totalLeavesQuantity); } // Working Order Working Quantity (Total Source Quantity - Total Executed Quantity) if (fields[Field.SourceOrder] || fields[Field.Execution]) { AddAttribute("WorkingQuantity", this.totalWorkingQuantity); } // Start Time if (fields[Field.StartTime] && !workingOrderRow.IsStartTimeNull()) { AddAttribute("StartTime", workingOrderRow.StartTime.ToString("s")); } // Stop Time if (fields[Field.StopTime] && !workingOrderRow.IsStopTimeNull()) { AddAttribute("StopTime", workingOrderRow.StopTime.ToString("s")); } // Maxmimum Volatility if (fields[Field.MaximumVolatility] && !workingOrderRow.IsMaximumVolatilityNull()) { AddAttribute("MaximumVolatility", workingOrderRow.MaximumVolatility); } // News Free Time if (fields[Field.NewsFreeTime] && !workingOrderRow.IsNewsFreeTimeNull()) { AddAttribute("NewsFreeTime", workingOrderRow.NewsFreeTime); } // Timer Field if (fields[Field.Timer]) { TimeSpan timeLeft = workingOrderRow.TimerRow.StopTime.Subtract(workingOrderRow.TimerRow.CurrentTime); AddAttribute("TimeLeft", string.Format("{0:0}:{1:00}", timeLeft.Minutes, timeLeft.Seconds)); } // The Working Order Fields if (fields[Field.WorkingOrder]) { // Created AddAttribute("CreatedName", workingOrderRow.UserRowByUserWorkingOrderCreatedUserId.ObjectRow.Name); AddAttribute("CreatedTime", workingOrderRow.CreatedTime.ToString("s")); // Destination if (!workingOrderRow.IsDestinationIdNull()) { AddAttribute("DestinationId", workingOrderRow.DestinationRow.DestinationId); AddAttribute("DestinationName", workingOrderRow.DestinationRow.Name); AddAttribute("DestinationShortName", workingOrderRow.DestinationRow.ShortName); } // The Direction of this order (buy, sell, buy cover, etc.) AddAttribute("PriceTypeCode", workingOrderRow.PriceTypeRow.PriceTypeCode); AddAttribute("PriceTypeMnemonic", workingOrderRow.PriceTypeRow.Mnemonic); // Commission AddAttribute("Commission", this.totalCommission); // FilledNet AddAttribute("NetMarketValue", this.totalMarketValue - workingOrderRow.OrderTypeRow.CashSign * this.totalCommission); // Market // AddAttribute("MarketId", workingOrderRow.SecurityRowByFKSecurityWorkingOrderSecurityId.MarketRow.MarketId); // AddAttribute("MarketName", workingOrderRow.SecurityRowByFKSecurityWorkingOrderSecurityId.MarketRow.Name); // AddAttribute("MarketShortName", workingOrderRow.SecurityRowByFKSecurityWorkingOrderSecurityId.MarketRow.ShortName); // LimitPrice // NOTE: LimitPrice is not sent when the WorkingOrder flag is set. // LimitPrice has a separate bit set in the field arary // Stop Price if (!workingOrderRow.IsStopPriceNull()) { AddAttribute("StopPrice", (decimal)workingOrderRow.StopPrice); } // TradeDate AddAttribute("TradeDate", workingOrderRow.CreatedTime.ToString("s")); // UploadTime if (!workingOrderRow.IsUploadedTimeNull()) { AddAttribute("UploadTime", workingOrderRow.CreatedTime.ToString("s")); } // CommissionType // if (workingOrderRow != null) // { // ClientMarketData.CommissionRateTypeRow commissionRateTypeRow = // ClientMarketData.CommissionRateType.FindByCommissionRateTypeCode((int)this.commissionRateTypeCode); // AddAttribute("CommissionRateTypeCode", commissionRateTypeRow.CommissionRateTypeCode); // AddAttribute("CommissionRateTypeName", commissionRateTypeRow.Name); // AddAttribute("CommissionRate", this.averageCommissionRate); // } // Filled Gross AddAttribute("MarketValue", this.totalMarketValue); // Unfilled AddAttribute("Unfilled", this.totalSourceOrderedQuantity - this.totalExecutedQuantity); } // Find the pricing record. if (!workingOrderRow.IsSettlementIdNull()) { ClientMarketData.PriceRow priceRow = ClientMarketData.Price.FindBySecurityId(workingOrderRow.SecurityId); if (priceRow != null) { if (fields[Field.LastPrice]) { AddAttribute("LastPrice", priceRow.LastPrice); } if (fields[Field.BidPrice]) { AddAttribute("BidPrice", priceRow.BidPrice); } if (fields[Field.AskPrice]) { AddAttribute("AskPrice", priceRow.AskPrice); } if (fields[Field.LastSize]) { AddAttribute("LastSize", priceRow.LastSize); } if (fields[Field.BidSize]) { AddAttribute("BidSize", priceRow.BidSize); } if (fields[Field.AskPrice]) { AddAttribute("AskSize", priceRow.AskSize); } if (fields[Field.Volume]) { AddAttribute("Volume", priceRow.Volume); } if (fields[Field.InterpolatedVolume]) { AddAttribute("InterpolatedVolume", VolumeHelper.CurrentVolumePercentage(DateTime.Now, workingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId.AverageDailyVolume, priceRow.Volume)); } if (fields[Field.VolumeWeightedAveragePrice]) { AddAttribute("VolumeWeightedAveragePrice", priceRow.VolumeWeightedAveragePrice); } } } }