}// AddBook() // // // ************************************************************* // **** Quote() **** // ************************************************************* // // /// <summary> /// This sets the inner market price and qty for the trade. /// For now it assumes the strategy has only one OrderInstrument, which is always /// the case when we have an "ExecutionStrategy" deployed; eg, an autospreader. /// /// qty must be signed, negative for sell qty's /// /// This will validate all prices prior to setting them. /// </summary> /// <param name="tradeSide"></param> /// <param name="price"></param> /// <param name="qty">Signed qty</param> /// <param name="aBook"></param> public void Quote(int tradeSide, double price, int qty, UV.Lib.BookHubs.Book aBook) { if (qty != 0 && tradeSide != QTMath.MktSignToMktSide(qty)) { // mismatch qty and sides Log.NewEntry(LogLevel.Warning, "Quote: tradeSide and side implied by qty sign do not match, rejecting quote update"); return; } if (!m_IsMarketReady) { // we cant't even validate prices yet. Log.NewEntry(LogLevel.Major, "Quote: Market has not been intialized yet. Order's will not be sent until market is intialized"); return; } if (!QTMath.IsPriceEqual(m_StrategyWorkingPrice[tradeSide], price, m_InstrumentDetails.TickSize)) { // price is different. if (m_RiskManager.ValidatePrices(price, tradeSide, m_Instrument, aBook)) { // our prices are valid so we can save variables m_StrategyWorkingPrice[tradeSide] = price; m_TotalDesiredQty[tradeSide] = qty; } } else { // price hasn't changed so if it was already set m_TotalDesiredQty[tradeSide] = qty; } Quote(); // go ahead an update our orders }//Quote()
// ***************************************************** // **** TimerSubscriberUpdate() **** // ***************************************************** public void TimerSubscriberUpdate(UV.Lib.BookHubs.Book aBook) { double midPrice = 0.5 * (this.ImpliedMarket.Price[BidSide][0] + this.ImpliedMarket.Price[AskSide][0]); for (int tradeSide = 0; tradeSide < 2; tradeSide++) { if (m_IsPriceInitialized[tradeSide] && System.Math.Abs(m_TotalQty[tradeSide]) > System.Math.Abs(m_ExecutedQty[tradeSide]) && m_IsTradingEnabled) { m_GraphEngine.AddPoint(m_GraphID, UV.Lib.Utilities.QTMath.MktSideToLongString(tradeSide), m_Price[tradeSide]); } } m_GraphEngine.AddPoint(m_GraphID, "Price", midPrice); }
// // private bool PnLCheck(UV.Lib.BookHubs.Book aBook) { double midPrice = (aBook.Instruments[m_InstrExternalId].Price[UV.Lib.Utilities.QTMath.BidSide][0] + aBook.Instruments[m_InstrExternalId].Price[UV.Lib.Utilities.QTMath.AskSide][0]) / 2; m_PnL = m_OrderEngine.m_FillBook.m_RealizedGain + m_OrderEngine.m_FillBook.UnrealizedDollarGains(midPrice); if (m_PnL < m_MaxLossPnL) { m_Log.NewEntry(LogLevel.Error, "Max Loss PnL Has Been Exceeded: Current PnL = {0} MaxLossPnL = {1}", m_PnL, m_MaxLossPnL); return(true); } else { return(false); } }
// ***************************************************************** // **** Public Methods **** // ***************************************************************** // // public override void MarketInstrumentInitialized(UV.Lib.BookHubs.Book marketBook) { base.MarketInstrumentInitialized(marketBook); if (m_IsTradingEnabled) { if (!m_IOrderEngineRemote.TrySetParameter("IsUserTradingEnabled", true)) // once we are all set allow orders to be sent out. { Log.NewEntry(LogLevel.Error, "{0} failed to set flag for IsUserTradingEnabled in IOrderEngine, no order will go out"); } } // // Plot historical values // List <DateTime> historicTimeStamp = null; List <double> historicStrategyMid = null; List <MarketDataItem[]> historicLegMarkets = null; if (base.TryGetTimeSeries(out historicTimeStamp, out historicStrategyMid, out historicLegMarkets)) { PlotHistoricData(m_GraphID, "Price", historicTimeStamp, historicStrategyMid); } }
// ************************************************************* // **** Market Change() **** // ************************************************************* /// <summary> /// Called whenever the market changes. /// </summary> /// <param name="marketBook"></param> /// <returns></returns> public override bool MarketInstrumentChanged(UV.Lib.BookHubs.Book marketBook, UV.Lib.BookHubs.InstrumentChangeArgs eventArgs) { base.MarketInstrumentChanged(marketBook, eventArgs); return(false); }
// // /// <summary> /// Called prior to updating prices in a strategy to make sure our prices are valid. /// /// This is the overload that must be called if you currenttly are holding the book /// </summary> /// <param name="desiredPrice"></param> /// <param name="mktSide"></param> /// <param name="instrName"></param> /// <param name="aBook"></param> /// <returns></returns> public bool ValidatePrices(double desiredPrice, int mktSide, InstrumentName instrName, UV.Lib.BookHubs.Book aBook) { if (m_Leg.InstrumentName != instrName) { m_Log.NewEntry(LogLevel.Error, "{0} Submitted Price Check To Risk Manager That Does Not Manage Risk For That Instrument"); return(false); } int mktSign = UV.Lib.Utilities.QTMath.MktSideToMktSign(mktSide); // sign of the market we are looking to execute on int oppMktSign = mktSign * -1; // opposite sign int oppMktSide = UV.Lib.Utilities.QTMath.MktSignToMktSide(oppMktSign); // opposite side double oppMktPrice = aBook.Instruments[m_InstrExternalId].Price[oppMktSide][0]; // best bid/offer (aggressible) price double allowedPrice = oppMktPrice + (m_FatFingerPriceTolerance * mktSign); // this is the max allowable price that we are allow to buy/sell if ((desiredPrice * mktSign) >= (allowedPrice * mktSign)) // this should correctly avoid us executing any prices outside our tolerances. { m_Log.NewEntry(LogLevel.Error, "Risk Check has Rejected Your Price Update To {0}, Price must be better than {1}", desiredPrice, allowedPrice); return(false); } else { return(true); } }