//
        //
        //
        //
        #endregion//Public Methods

        #region Private Methods
        // *****************************************************************
        // ****                     Private Methods                     ****
        // *****************************************************************
        //
        //
        // *****************************************************************
        // ****                     RunHedgeLogic()                     ****
        // *****************************************************************
        /// <summary>
        /// Called after Instrument_TickChanged to update hedge prices of
        /// orders under active management by the HedgeRuleManager.
        /// </summary>
        private void RunHedgeLogic()
        {
            double endingPrice;                                                                     // price we end up with after our rules are applied.
            double userDefinedWorstPrice;                                                           // price the user has defined as the worst possible price

            if (m_OrderBook.Count() == 0)
            {                                                                                 // we have no orders to manage
                m_isManagerActive = false;
                m_QuoterLeg.m_Market.MarketChanged -= new EventHandler(Market_MarketChanged); // subscribe to orders state changes for this leg.
                m_Log.NewEntry(LogLevel.Minor, "HedgeRuleManager : {0} has no orders to manage, Unsunbscribing from market", m_QuoterLeg.InstrumentDetails.InstrumentName);
                return;
            }
            else // we have orders and need to manage them
            {
                for (int mktSide = 0; mktSide < 2; ++mktSide)
                {                                                                 // each side of market
                    if (m_OrderBook.Count(mktSide) != 0)
                    {                                                             //we have orders on this side of the market
                        m_ActiveOrders.Clear();                                   // these can not be recycled since the hedger could still be holding an order.
                        m_OrderBook.GetOrdersBySide(mktSide, ref m_ActiveOrders); // populate all orders for this side of the market
                        foreach (int id in m_ActiveOrders.Keys)
                        {
                            if (m_ActiveOrders.TryGetValue(id, out tmpOrder))
                            { // we can find the order
                                int orderSign = QTMath.MktSideToMktSign(tmpOrder.Side);
                                if (!m_OrderIdToUserDefinedWorstPrice.ContainsKey(id))
                                {
                                    userDefinedWorstPrice = tmpOrder.PricePending + (orderSign * tmpOrder.TickSize * m_MaxPayUpTicks);
                                    m_OrderIdToUserDefinedWorstPrice.Add(id, userDefinedWorstPrice);
                                }
                                else
                                {
                                    userDefinedWorstPrice = m_OrderIdToUserDefinedWorstPrice[tmpOrder.Id];
                                }

                                endingPrice = tmpOrder.PricePending;                                                    // assume we have no change to start.
                                foreach (IHedgeRule rule in m_HedgeRules)
                                {                                                                                       // apply our hedge rules
                                    bool isContinue = rule.ApplyHedgeRule(endingPrice, tmpOrder.Side, out endingPrice); // hand the function the ending price and let it update it
                                    if (!isContinue)                                                                    // we want to execute our rule immediately
                                    {
                                        break;
                                    }
                                }

                                if ((endingPrice * orderSign) > userDefinedWorstPrice * orderSign)  // if our ending price is worse than worse price, reassing it.
                                {
                                    endingPrice = userDefinedWorstPrice;
                                }

                                if (!QTMath.IsPriceEqual(endingPrice, tmpOrder.PricePending, tmpOrder.TickSize))
                                {                                                           // our price has been changed
                                    m_Hedger.UpdateHedgerOrderPrice(tmpOrder, endingPrice); // call the hedger to change the order
                                }
                            }
                        } // end foreach
                    }     // end if
                }         // end mktside
            }             // end else
        }                 // RunHedgeLogic()
        //
        // *************************************************************
        // ****                      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>
        public void Quote(int tradeSide, double price, int qty)
        {
            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_IsLegSetUpComplete)
            { // 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;
            }

            price = price / m_PriceLeg.PriceMultiplier;             // convert from strat price to instrument price
            qty   = (int)(qty * Math.Abs(m_PriceLeg.Weight));       // convert from strat qty to instrument qty

            if (!QTMath.IsPriceEqual(m_StrategyWorkingPrice[tradeSide], price, m_InstrumentDetails.TickSize) || m_TotalDesiredQty[tradeSide] != qty)
            {     // price is different.
                if (m_RiskManager.ValidatePrices(price, tradeSide, m_PriceLeg.InstrumentName) || qty == 0)
                { // our prices are valid so we can save variables
                    m_StrategyWorkingPrice[tradeSide] = price;
                    m_TotalDesiredQty[tradeSide]      = qty;
                    Log.NewEntry(LogLevel.Major, "Quote:{4} Working {1} {0} @ {2} in {3}", // while this may be silly to log first, it is here for readability
                                 m_OpenSyntheticOrders[tradeSide].TradeReason,             // 0
                                 qty,                                                      // 1
                                 price,                                                    // 2
                                 m_InstrumentDetails.InstrumentName,                       //3
                                 m_ExecutionContainer.EngineContainerID);                  //4
                    Quote();                                                               // go ahead an update our orders
                }
            }
        }//Quote()
Example #3
0
        // *****************************************************************
        // ****                     Private Methods                     ****
        // *****************************************************************
        //
        //
        //
        //**********************************************************
        //****             Update Market Prices()               ****
        //**********************************************************
        /// <summary>
        /// Called whenever the mkt changes.  Updates m_Prices[][] and m_Qtys[][].
        /// returns True if inside market has changed prices
        /// </summary>
        /// TODO: THIS NEEDS TO BE FIXED
        private bool UpdateMarketPrices(UV.Lib.BookHubs.Market market, List <int>[] MarketDepthChangedList)
        {
            bool isChanged = false;

            for (int side = 0; side < 2; ++side)
            {
                if (MarketDepthChangedList[side].Count == 0 || MarketDepthChangedList[side][0] > m_LeanableDepth[side] || MarketDepthChangedList[side][0] > m_OrderBookDepthMax)
                { // if no change on this side || top change is past our leanable depth || top change is past the depth we care about
                  //nothing to do here!
                }
                else
                {     // this is a price or qty change that we need to consider
                    if (MarketDepthChangedList[side][0] == 0 && !QTMath.IsPriceEqual(m_Market.Price[side][MarketDepthChangedList[side][0]], market.Price[side][0], InstrumentDetails.TickSize))
                    { // if this is a top of book price change!
                        isChanged = true;
                    }
                    foreach (int level in MarketDepthChangedList[side])
                    {     // Set new internal market from the depth changed back
                        if (level < m_OrderBookDepthMax)
                        { // we care about updates at this level
                            m_Market.Price[side][level] = market.Price[side][level];
                            m_Market.Qty[side][level]   = market.Qty[side][level];
                        }
                    }
                }
            }
            return(isChanged);
        }
Example #4
0
        }// 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()
Example #5
0
        }//Quote()

        //
        //
        #endregion//Public Methods

        #region Private Methods
        // *****************************************************************
        // ****                     Private Methods                     ****
        // *****************************************************************
        //
        //
        // *************************************************************
        // ****                      Quote()                        ****
        // *************************************************************
        /// <summary>
        /// This private method can be called on any state change to update our orders
        /// in the market once all our internal prices, flags, and states are set.
        /// </summary>
        private void Quote()
        {
            bool isAllowedToWorkOrder;
            int  marketSign;
            int  qtyToWork;

            for (int side = 0; side < 2; side++)
            {
                marketSign           = QTMath.MktSideToMktSign(side);
                isAllowedToWorkOrder = (Math.Abs(m_StrategyPosition[side]) < Math.Abs(m_TotalDesiredQty[side])) && m_IsRiskCheckPassed && m_DripQty > 0;
                // find our working order.
                m_OrderWorkSpace.Clear();
                m_OrderBook.GetOrdersByRank(side, 0, ref m_OrderWorkSpace);
                Order quoteOrder = null;
                int   nthOrder   = 0;
                while (nthOrder < m_OrderWorkSpace.Count && quoteOrder == null)                                     // loop until we find a living quoteOrder
                {
                    if (m_OrderWorkSpace[nthOrder].OrderStateConfirmed != OrderState.Dead)
                    {
                        quoteOrder = m_OrderWorkSpace[nthOrder];
                    }
                    nthOrder++;
                }
                if (isAllowedToWorkOrder)
                {
                    qtyToWork = QTMath.CalculateDripQty(m_DripQty, m_TotalDesiredQty[side], m_StrategyPosition[side]);
                    int iPrice = (int)(m_StrategyWorkingPrice[side] / m_InstrumentDetails.TickSize);
                    if (quoteOrder == null && qtyToWork != 0)
                    { // we aren't working an order, but would like to be
                        Order order;
                        if (m_OrderHub.TryCreateOrder(m_Instrument, side, iPrice, qtyToWork, out order))
                        {
                            if (m_UseGTC)
                            {
                                order.OrderTIF = OrderTIF.GTC;
                            }
                            m_OrderHub.TrySubmitOrder(m_OrderBook.BookID, order);
                            m_RiskManager.m_NumberOfQuotesThisSecond++;
                        }
                    }
                    else if (!QTMath.IsPriceEqual(quoteOrder.PricePending, m_StrategyWorkingPrice[side], m_InstrumentDetails.TickSize) ||
                             quoteOrder.WorkingQtyPending != qtyToWork)
                    {                                                                            // we need to change price, qty, or both
                        if (m_OrderHub.TryChangeOrderPriceAndQty(quoteOrder, qtyToWork, iPrice)) // this will handle everthing for us!
                        {
                            m_RiskManager.m_NumberOfQuotesThisSecond += 2;                       // cancel and replace = 2?
                        }
                        else
                        {
                            Log.NewEntry(LogLevel.Warning, "Quote: Failed To Modify order {0}", quoteOrder);            // do we want to do anything more here?
                        }
                    }
                }
                else if (quoteOrder != null)
                { // we are working an order, but don't want to be!
                    if (!m_OrderHub.TryDeleteOrder(quoteOrder))
                    {
                        Log.NewEntry(LogLevel.Warning, "Quote: Failed to canel order {0}", quoteOrder);
                    }
                }
            }
        }//Quote()