// // // // #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()
// // // // // ******************************************************* // **** OrderBook_OrderFilled() **** // ******************************************************* /// <summary> /// Called when an order in the hedge order book has been filled. /// </summary> /// <param name="sender"></param> /// <param name="eventArgs"></param> private void OrderBook_OrderFilled(object sender, EventArgs eventArgs) { FillEventArgs fillEventArgs = (FillEventArgs)eventArgs; Fill fill = fillEventArgs.Fill; int internalLegId = m_Spreader.m_InstrumentToInternalId[fillEventArgs.InstrumentName]; int stratSign = Math.Sign(fill.Qty * m_Spreader.m_LegRatios[internalLegId]); int stratSide = UV.Lib.Utilities.QTMath.MktSignToMktSide(stratSign); // Update my IsLegHung status bool prevHungState = m_IsLegHung[stratSide]; // Keep prev state so we know it has changed. m_IsLegHung[stratSide] = false; m_Spreader.AddHedgeFill(stratSide, internalLegId, fill); // this needs to get updated prior to us trigger OnCompletelyFilled int legSide = UV.Lib.Utilities.QTMath.MktSignToMktSide(m_Spreader.m_LegRatios[m_InternalLegId] * stratSign); if (m_OrderBook.Count(legSide) != 0) { m_IsLegHung[stratSide] = true; // we have no outstanding hedge orders } else { OnCompletelyFilled(fillEventArgs); } }