/// <summary> /// Calculates the price of a debt issue. /// </summary> /// <param name="baseCurrency">The base currency for the requested price.</param> /// <param name="debtId">The identifier of a debt.</param> /// <returns>The price of the debt in the base currency</returns> public static decimal Debt(DataModel.CurrencyRow baseCurrency, DataModel.DebtRow debtRow) { // Look up the price in the security's native currency. DataModel.PriceRow securityPriceRow = DataModel.Price.FindBySecurityIdCurrencyId( debtRow.DebtId, debtRow.SettlementId); if (securityPriceRow == null) { return(0.0M); } // Look up the cross currency value. This is needed to return the value in the requested base currency. DataModel.PriceRow crossPriceRow = DataModel.Price.FindBySecurityIdCurrencyId( debtRow.SettlementId, baseCurrency.CurrencyId); if (crossPriceRow == null) { return(0.0M); } // Use the User Preferences to determine which price (Last, Closing) we should use. decimal securityPrice = 0.0M; decimal crossPrice = 0.0M; if (Preferences.Pricing == Pricing.Last) { securityPrice = securityPriceRow.LastPrice; crossPrice = crossPriceRow.LastPrice; } if (Preferences.Pricing == Pricing.Close) { securityPrice = securityPriceRow.ClosePrice; crossPrice = crossPriceRow.ClosePrice; } // The price, in the requested currency, is the native price multiplied by the cross currency price and any factors. return(securityPrice * crossPrice); }
/// <summary> /// Create an equity working order. /// </summary> void CreateEquity() { // All orders get a unique identifier. Guid workingOrderId = Guid.NewGuid(); // These records provide the starting point for generating the orders. DataModel.BlotterRow blotterRow = DataModel.Blotter.BlotterKey.Find(generatorInfo.BlotterId); DataModel.UserRow userRow = DataModel.User.UserKey.Find(generatorInfo.UserId); DataModel.CountryRow unitedStatesRow = DataModel.Country.CountryKeyExternalId0.Find("US"); DataModel.StatusRow statusRow = DataModel.Status.StatusKey.Find(StatusCode.New); // Generate the settlement currency DataModel.EntityRow usdEntityRow = DataModel.Entity.EntityKeyExternalId0.Find("USD"); DataModel.SecurityRow settlementCurrencyRow = DataModel.Security.SecurityKey.Find(usdEntityRow.EntityId); // The orders are an even mix of Buys and Sells. Most positions are long. Boolean isBuy = random.Next(2) == 0; Boolean isLong = random.Next(4) != 0; SideCode sideCode = isBuy && isLong ? SideCode.Buy : !isBuy && isLong ? SideCode.Sell : isBuy && !isLong ? SideCode.BuyCover : SideCode.SellShort; DataModel.SideRow sideRow = DataModel.Side.SideKey.Find(sideCode); // Find a random equity position that is unique to this blotter. DataModel.SecurityRow securityRow = null; while (securityRow == null) { // Select a random equity and price for the next order. DataModel.EquityRow equityRow = DataModel.Equity[random.Next(DataModel.Equity.Count - 1)]; DataModel.PriceRow priceRow = DataModel.Price.PriceKey.Find(equityRow.EquityId, settlementCurrencyRow.SecurityId); // Only generate orders for securities that are unique to this blotter and for which we have prices. It is important when the price simulator runs // that we don't have zeros showing up for prices as it requires more explaination that we want to provide. Position position = new Position(equityRow.EquityId, sideCode); if (!positionSet.Contains(position) && priceRow != null) { securityRow = equityRow.SecurityRowByFK_Security_Equity_EquityId; positionSet.Add(position); } } // These orders will not match by default. We need to turn them on manually. DataModel.CrossingRow crossingRow = DataModel.Crossing.CrossingKey.Find(CrossingCode.NeverMatch); // Select a random Time In Force for this order. Most orders are Day orders but occationally we'll generate a GTC just to keep it interesting. TimeInForceCode timeInForce = random.Next(4) == 0 ? TimeInForceCode.GoodTillCancel : TimeInForceCode.Day; DataModel.TimeInForceRow timeInForceRow = DataModel.TimeInForce.TimeInForceKey.Find(timeInForce); // Generate the trade and settlement dates based on the current time and make sure it doesn't fall on a weekend. DateTime tradeDate = DateTime.Now; DateTime settlementDate = DateTime.Now; TimeSpan oneDay = TimeSpan.FromDays(1.0); for (Int32 dayIndex = 0; dayIndex < 3; dayIndex++) { settlementDate += oneDay; if (settlementDate.DayOfWeek == DayOfWeek.Saturday) { settlementDate += oneDay; } if (settlementDate.DayOfWeek == DayOfWeek.Sunday) { settlementDate += oneDay; } } // This will generate random matching preferences for the orders for demonstrating the matching box capabilities. Boolean isBrokerMatch = random.Next(20) == 0; Boolean isHedgeMatch = random.Next(15) == 0; Boolean isInstitutionMatch = true; // This randomizes the random matching patterns. Every now and then, don't match with anyone. if (random.Next(5) == 0) { isBrokerMatch = false; isHedgeMatch = false; isInstitutionMatch = false; } // <transaction> XElement elementTransaction = new XElement("transaction"); this.xDocument.Root.Add(elementTransaction); // <method name="StoreWorkingOrder"> XElement elementWorkingOrder = new XElement("method", new XAttribute("name", "StoreWorkingOrder")); elementTransaction.Add(elementWorkingOrder); // <parameter name="blotterKey" value="EMERGING MARKETS BLOTTER" /> elementWorkingOrder.Add( new XElement("parameter", new XAttribute("name", "blotterKey"), new XAttribute("value", blotterRow.EntityRow.ExternalId0))); // <parameter name="configurationId" value="US TICKER" /> elementWorkingOrder.Add(new XElement("parameter", new XAttribute("name", "configurationId"), new XAttribute("value", "US TICKER"))); // <parameter name="createdTime" value="5/6/2012 5:27:56 PM" /> elementWorkingOrder.Add(new XElement("parameter", new XAttribute("name", "createdTime"), new XAttribute("value", DateTime.Now.ToString("G")))); // <parameter name="crossingKey" value="NEVER MATCH" /> elementWorkingOrder.Add(new XElement("parameter", new XAttribute("name", "crossingKey"), new XAttribute("value", crossingRow.ExternalId0))); // <parameter name="externalId0" value="{bab88942-5c4e-440a-a352-c8e9b00fec12}" /> elementWorkingOrder.Add(new XElement("parameter", new XAttribute("name", "externalId0"), new XAttribute("value", workingOrderId.ToString("B")))); // <parameter name="isBrokerMatch" value="false" /> elementWorkingOrder.Add(new XElement("parameter", new XAttribute("name", "isBrokerMatch"), new XAttribute("value", isBrokerMatch))); // <parameter name="isHedgeMatch" value="false" /> elementWorkingOrder.Add(new XElement("parameter", new XAttribute("name", "isHedgeMatch"), new XAttribute("value", isHedgeMatch))); // <parameter name="isInstitutionMatch" value="true" /> elementWorkingOrder.Add(new XElement("parameter", new XAttribute("name", "isInstitutionMatch"), new XAttribute("value", isInstitutionMatch))); // <parameter name="modifiedTime" value="5/6/2012 5:27:56 PM" /> elementWorkingOrder.Add(new XElement("parameter", new XAttribute("name", "modifiedTime"), new XAttribute("value", DateTime.Now.ToString("G")))); // <parameter name="orderTypeKey" value="MKT" /> elementWorkingOrder.Add(new XElement("parameter", new XAttribute("name", "orderTypeKey"), new XAttribute("value", "MKT"))); // <parameter name="securityKeyBySecurityId" value="ODP" /> elementWorkingOrder.Add( new XElement("parameter", new XAttribute("name", "securityKeyBySecurityId"), new XAttribute("value", securityRow.EntityRow.ExternalId3))); // <parameter name="securityKeyBySettlementId" value="USD" /> elementWorkingOrder.Add( new XElement("parameter", new XAttribute("name", "securityKeyBySettlementId"), new XAttribute("value", settlementCurrencyRow.EntityRow.ExternalId0))); // <parameter name="settlementDate" value="5/9/2012 5:27:56 PM" /> elementWorkingOrder.Add(new XElement("parameter", new XAttribute("name", "settlementDate"), new XAttribute("value", settlementDate.ToString("G")))); // <parameter name="sideKey" value="SELL" /> elementWorkingOrder.Add(new XElement("parameter", new XAttribute("name", "sideKey"), new XAttribute("value", sideRow.ExternalId0))); // <parameter name="statusKey" value="NEW" /> elementWorkingOrder.Add(new XElement("parameter", new XAttribute("name", "statusKey"), new XAttribute("value", statusRow.ExternalId0))); // <parameter name="timeInForceKey" value="DAY" /> elementWorkingOrder.Add(new XElement("parameter", new XAttribute("name", "timeInForceKey"), new XAttribute("value", timeInForceRow.ExternalId0))); // <parameter name="tradeDate" value="5/6/2012 5:27:56 PM" /> elementWorkingOrder.Add(new XElement("parameter", new XAttribute("name", "tradeDate"), new XAttribute("value", tradeDate.ToString("G")))); // <parameter name="userKeyByCreatedUserId" value="DEV KAPOOR" /> elementWorkingOrder.Add( new XElement("parameter", new XAttribute("name", "userKeyByCreatedUserId"), new XAttribute("value", userRow.EntityRow.ExternalId0))); // <parameter name="userKeyByModifiedUserId" value="DEV KAPOOR" /> elementWorkingOrder.Add( new XElement("parameter", new XAttribute("name", "userKeyByModifiedUserId"), new XAttribute("value", userRow.EntityRow.ExternalId0))); // This will generate between one and six source orders for the working order. Source orders are a blocking concept. You can get several orders for // the same security on the same side for the same price. When this happens, it is much more efficient to block them as a single order and execute them // as a single order and allocate them back to the original orders when the order is done. Int32 sourceOrderCount = random.Next(1, 6); for (Int32 sourceOrderIndex = 0; sourceOrderIndex < sourceOrderCount; sourceOrderIndex++) { // This creates a unique identifier for the source order. Guid sourceOrderId = Guid.NewGuid(); // This generates a random quantity for the order between 100 and 10,000 shares. Decimal orderedQuantity = Convert.ToDecimal(random.Next(1, 100)) * 100.0M; // <method name="StoreSourceOrder"> XElement elementSourceOrder = new XElement("method", new XAttribute("name", "StoreSourceOrder")); elementTransaction.Add(elementSourceOrder); // <parameter name="configurationId" value="US TICKER" /> elementSourceOrder.Add(new XElement("parameter", new XAttribute("name", "configurationId"), new XAttribute("value", "US TICKER"))); // <parameter name="createdTime" value="2012-05-06T17:27:56.2658093-04:00" /> elementSourceOrder.Add(new XElement("parameter", new XAttribute("name", "createdTime"), new XAttribute("value", DateTime.Now))); // <parameter name="externalId0" value="{3c69e0a0-3316-4499-a7b1-6dda5a058837}" /> elementSourceOrder.Add(new XElement("parameter", new XAttribute("name", "externalId0"), new XAttribute("value", sourceOrderId.ToString("B")))); // <parameter name="modifiedTime" value="5/6/2012 5:27:56 PM" /> elementSourceOrder.Add(new XElement("parameter", new XAttribute("name", "modifiedTime"), new XAttribute("value", DateTime.Now.ToString("G")))); // <parameter name="orderedQuantity" value="4300.0" /> elementSourceOrder.Add(new XElement("parameter", new XAttribute("name", "orderedQuantity"), new XAttribute("value", orderedQuantity))); // <parameter name="orderTypeKey" value="MKT" /> elementSourceOrder.Add(new XElement("parameter", new XAttribute("name", "orderTypeKey"), new XAttribute("value", "MKT"))); // <parameter name="securityKeyBySecurityId" value="ODP" /> elementSourceOrder.Add( new XElement("parameter", new XAttribute("name", "securityKeyBySecurityId"), new XAttribute("value", securityRow.EntityRow.ExternalId3))); // <parameter name="securityKeyBySettlementId" value="USD" /> elementSourceOrder.Add( new XElement("parameter", new XAttribute("name", "securityKeyBySettlementId"), new XAttribute("value", settlementCurrencyRow.EntityRow.ExternalId0))); // <parameter name="settlementDate" value="2012-05-09T17:27:56.2528086-04:00" /> elementSourceOrder.Add(new XElement("parameter", new XAttribute("name", "settlementDate"), new XAttribute("value", settlementDate))); // <parameter name="sideKey" value="SELL" /> elementSourceOrder.Add(new XElement("parameter", new XAttribute("name", "sideKey"), new XAttribute("value", sideRow.ExternalId0))); // <parameter name="statusKey" value="NEW" /> elementSourceOrder.Add(new XElement("parameter", new XAttribute("name", "statusKey"), new XAttribute("value", statusRow.ExternalId0))); // <parameter name="timeInForceKey" value="DAY" /> elementSourceOrder.Add( new XElement("parameter", new XAttribute("name", "timeInForceKey"), new XAttribute("value", timeInForceRow.ExternalId0))); // <parameter name="tradeDate" value="5/6/2012 5:27:56 PM" /> elementSourceOrder.Add(new XElement("parameter", new XAttribute("name", "tradeDate"), new XAttribute("value", tradeDate.ToString("G")))); // <parameter name="userKeyByCreatedUserId" value="DEV KAPOOR" /> elementSourceOrder.Add( new XElement("parameter", new XAttribute("name", "userKeyByCreatedUserId"), new XAttribute("value", userRow.EntityRow.ExternalId0))); // <parameter name="userKeyByModifiedUserId" value="DEV KAPOOR" /> elementSourceOrder.Add( new XElement("parameter", new XAttribute("name", "userKeyByModifiedUserId"), new XAttribute("value", userRow.EntityRow.ExternalId0))); // <parameter name="workingOrderKey" value="{bab88942-5c4e-440a-a352-c8e9b00fec12}" /> elementSourceOrder.Add( new XElement("parameter", new XAttribute("name", "workingOrderKey"), new XAttribute("value", workingOrderId.ToString("B")))); } }
/// <summary> /// Copy the values from the data model. /// </summary> /// <param name="workingOrderRow">The data model row that is the source of the data.</param> public virtual void Copy(DataModel.WorkingOrderRow workingOrderRow) { // Validate the parameters. if (workingOrderRow == null) { throw new ArgumentNullException("workingOrderRow"); } // Find the price associated with the security in this order and copy. DataModel.PriceRow priceRow = DataModel.Price.PriceKey.Find( workingOrderRow.SecurityRowByFK_Security_WorkingOrder_SecurityId.SecurityId, workingOrderRow.SecurityRowByFK_Security_WorkingOrder_SettlementId.SecurityId); if (priceRow != null) { this.AskPrice.Price = priceRow.AskPrice; this.BidPrice.Price = priceRow.BidPrice; this.LastPrice.Price = priceRow.LastPrice; } // Any order that is not filled is considered active. this.IsActive = workingOrderRow.StatusRow.StatusCode != StatusCode.Filled; // Copy the scalar values directly from the data model. this.BlotterName = workingOrderRow.BlotterRow.EntityRow.Name; this.CreatedBy = workingOrderRow.UserRowByFK_User_WorkingOrder_CreatedUserId.EntityRow.Name; this.CreatedTime = workingOrderRow.CreatedTime; this.ModifiedBy = workingOrderRow.UserRowByFK_User_WorkingOrder_ModifiedUserId.EntityRow.Name; this.ModifiedTime = workingOrderRow.ModifiedTime; this.RowVersion = workingOrderRow.RowVersion; this.SecurityName = workingOrderRow.SecurityRowByFK_Security_WorkingOrder_SecurityId.EntityRow.Name; this.SideCode = workingOrderRow.SideRow.SideCode; this.SideMnemonic = workingOrderRow.SideRow.Mnemonic; this.SettlementDate = workingOrderRow.SettlementDate; this.StatusCode = workingOrderRow.StatusRow.StatusCode; this.Symbol = workingOrderRow.SecurityRowByFK_Security_WorkingOrder_SecurityId.Symbol; this.TradeDate = workingOrderRow.TradeDate; this.WorkingOrderId = workingOrderRow.WorkingOrderId; // These factors are needed to compute the proper quantities and prices. Decimal quantityFactor = workingOrderRow.SecurityRowByFK_Security_WorkingOrder_SecurityId.QuantityFactor; Decimal priceFactor = workingOrderRow.SecurityRowByFK_Security_WorkingOrder_SecurityId.PriceFactor; // Aggregate the Destiantion Order and Execution Quantities. Decimal destinationOrderQuantity = 0.0m; Decimal executionQuantity = 0.0m; foreach (DataModel.DestinationOrderRow destinationOrderRow in workingOrderRow.GetDestinationOrderRows()) { destinationOrderQuantity += destinationOrderRow.OrderedQuantity; foreach (DataModel.ExecutionRow executionRow in destinationOrderRow.GetExecutionRows()) { executionQuantity += executionRow.ExecutionQuantity; } } this.DestinationOrderQuantity = destinationOrderQuantity; this.ExecutionQuantity = executionQuantity; // Aggregate the Source Order Quantity. Decimal sourceOrderQuantity = 0.0m; foreach (DataModel.SourceOrderRow sourceOrderRow in workingOrderRow.GetSourceOrderRows()) { sourceOrderQuantity += sourceOrderRow.OrderedQuantity; } this.SourceOrderQuantity = sourceOrderQuantity; // These derived values must be calcualted after the value columns. this.AvailableQuantity = this.SourceOrderQuantity - this.DestinationOrderQuantity; this.MarketValue = sourceOrderQuantity * quantityFactor * this.LastPrice.Price * priceFactor; this.LeavesQuantity = this.DestinationOrderQuantity - this.ExecutionQuantity; }
/// <summary> /// Updates prices using a United States ticker. /// </summary> /// <param name="symbolIndex">The index to use to find the symbol.</param> /// <param name="symbolKey">The symbol key.</param> /// <param name="currencyIndex">The index to use to find the currency.</param> /// <param name="currencyKey">The currency key.</param> /// <param name="quote">The quote used to update the price.</param> static void UpdatePriceBySymbolCurrency( DataModel.IEntityIndex symbolIndex, Object[] symbolKey, DataModel.IEntityIndex currencyIndex, Object[] currencyKey, Quote quote) { // The current transaction and the target data model is extracted from the thread. DataModelTransaction dataModelTransaction = DataModel.CurrentTransaction; TenantDataModel tenantDataSet = dataModelTransaction.TenantDataModel; // This will find the currency of the quote. DataModel.EntityRow currencyEntityRow = currencyIndex.Find(currencyKey); if (currencyEntityRow == null) { throw new FaultException <RecordNotFoundFault>(new RecordNotFoundFault("Entity", currencyKey)); } currencyEntityRow.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout); dataModelTransaction.AddLock(currencyEntityRow); if (currencyEntityRow.RowState == System.Data.DataRowState.Detached) { throw new FaultException <RecordNotFoundFault>(new RecordNotFoundFault("Entity", currencyKey)); } Guid currencyId = currencyEntityRow.EntityId; // This will find the security using the external identifier. DataModel.EntityRow securityEntityRow = symbolIndex.Find(symbolKey); if (securityEntityRow == null) { throw new FaultException <RecordNotFoundFault>(new RecordNotFoundFault("Entity", symbolKey)); } securityEntityRow.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout); dataModelTransaction.AddLock(securityEntityRow); if (securityEntityRow.RowState == System.Data.DataRowState.Detached) { throw new FaultException <RecordNotFoundFault>(new RecordNotFoundFault("Entity", symbolKey)); } Guid securityId = securityEntityRow.EntityId; // If the price record exists, then update it. If it doesn't exist then create it. Object[] priceKey = new Object[] { securityId, currencyId }; DataModel.PriceRow priceRow = DataModel.Price.PriceKey.Find(priceKey); if (priceRow == null) { tenantDataSet.CreatePrice( quote.AskPrice, quote.AskSize, quote.BidPrice, quote.BidSize, null, currencyId, null, quote.LastPrice, quote.LastSize, null, null, null, securityId, null, null); } else { priceRow.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout); dataModelTransaction.AddLock(priceRow); if (priceRow.RowState == System.Data.DataRowState.Detached) { throw new FaultException <RecordNotFoundFault>(new RecordNotFoundFault("Price", priceKey)); } tenantDataSet.UpdatePrice( quote.AskPrice, quote.AskSize, quote.BidPrice, quote.BidSize, null, currencyId, null, quote.LastPrice, quote.LastSize, null, null, null, priceKey, priceRow.RowVersion, securityId, null, null); } }