}// TryToStop() // // // // ***************************************** // **** Quote() **** // ***************************************** /// <summary> /// Method to request that an order engine send orders at a particular price and qty. /// qty should be a signed int. /// /// this overload allows for a quote reason to be sent along with the order. /// </summary> /// <param name="pricingEngine"></param> /// <param name="tradeSide"></param> /// <param name="price"></param> /// <param name="qty"></param> /// <param name="quoteReason">Explanation for logging purposes.</param> public void Quote(PricingEngine pricingEngine, int tradeSide, double price, int qty, QuoteReason quoteReason = QuoteReason.None) { if (!m_IsBeginComplete) { StrategyHub.Log.NewEntry(LogLevel.Error, "Quote called before complete."); } if (!IsLaunched) { StrategyHub.Log.NewEntry(LogLevel.Error, "Quote called before launched."); } /* * if (m_OrderEngine != null) * { * int tradeId = m_OrderEngine.Quote(tradeSide, price, qty, quoteReason); * // Save pricing model update snapshot * m_ModelSnapshots[tradeId] = String.Format("{0} TradeReason={1}", m_PricingEngine.GetFillAttributeString(), quoteReason); // store snapshot in tradeId we just adjusted. * } */ m_QuoteEngine.Quote(pricingEngine, tradeSide, price, qty, quoteReason); }//Quote()
// #endregion//Properties #region Public Methods // ***************************************************************** // **** Public Methods **** // ***************************************************************** // // // // // ***************************************** // **** Quote() **** // ***************************************** /// <summary> /// Method called by PricingEngine to request a change in quoting /// for a particular, side, price and qty. /// Sending a quote with only tradeSide will remove quote from price list. /// /// Generally,s pricingEngines that don't want to quote a qty should still quote their target price. /// This allows overfills to be distributed to the pricing engine that can best use it. /// </summary> /// <param name="pricingEngine"></param> /// <param name="tradeSide"></param> /// <param name="price"></param> /// <param name="qty">signed integer</param> /// <param name="quoteReason">user chosen quote reason.</param> public virtual void Quote(PricingEngine pricingEngine, int tradeSide, double price = double.NaN, int qty = 0, QuoteReason quoteReason = QuoteReason.None) { // Compute quote variables. int tradeSign = UV.Lib.Utilities.QTMath.MktSideToMktSign(tradeSide); bool isPriceListed = (double.IsNaN(price) == false && double.IsInfinity(price) == false); int iPriceNew = 0; if (isPriceListed) { iPriceNew = tradeSign * (int)System.Math.Floor(tradeSign * price / m_QuoteTickSize); // integerized price! } // Get this engines quote object from our master list. Quote quote = null; if (!m_Quotes[tradeSide].TryGetValue(pricingEngine, out quote)) // we store quotes for each side of mkt. { // Apparently this is the first quote call from this engine. quote = new Quote(); m_Quotes[tradeSide].Add(pricingEngine, quote); quote.PricingEngine = pricingEngine; // set constant vars. quote.Side = tradeSide; if (m_FirstPriceEngine == null) { m_FirstPriceEngine = pricingEngine; } } bool isPriceListedPrev = quote.IsPriceListed; int iPricePrev = quote.IPrice; int qtyPrev = quote.Qty; // Test validity of qty value if (tradeSign * qty < 0) { qty = 0; } // Determine if this quote has changed. // isPriceChanged = should contain all reasons the quotes location in book might change. bool isPriceChanged = (isPriceListed != isPriceListedPrev) || (iPriceNew != iPricePrev) || (quote.Reason != quoteReason); bool doesThisChangeRequireQuoteUpdating = (qty != qtyPrev) || (isPriceChanged); m_IsQuoteSideUpdateRequired[tradeSide] = m_IsQuoteSideUpdateRequired[tradeSide] || doesThisChangeRequireQuoteUpdating; // true if ANY PricingEngines quotes have changed since last update. // If the price has changed, and it should have been in our price list, // we need to remove it from its old location in price list. if (isPriceChanged && isPriceListedPrev) { RemoveQuoteFromListing(tradeSide, quote); } // Update the quote with the new price/qty quote.IsPriceListed = isPriceListed; quote.IPrice = iPriceNew; quote.RawPrice = price; quote.Qty = qty; quote.Reason = quoteReason; quote.FillAttributeStr.Clear(); quote.FillAttributeStr.Append(pricingEngine.GetFillAttributeString()); // Now add quote to new price location, if necessary. if (isPriceChanged && isPriceListed) { // We need to add it since its price has changed, and it price is valid now. List <Quote> quoteList = null; int priceKey = -tradeSign * iPriceNew; if (!m_QuotesByPrice[tradeSide].TryGetValue(priceKey, out quoteList)) // get all quotes at this price { // There are no previous quotes at this price, create new list. quoteList = m_QuoteListRecycling.Get(); quoteList.Clear(); m_QuotesByPrice[tradeSide].Add(priceKey, quoteList); } // Add quote to list at this price. if (quote.Reason == QuoteReason.Exit || quote.Reason == QuoteReason.Stop) { quoteList.Insert(0, quote); // put these in the front of the list. } else { quoteList.Add(quote); // add these to end of list. } } }//Quote()