Example #1
0
        }//TryChangeOrderPriceAndQty()

        //
        // *********************************************
        // **** Try Process Order Update Request()  ****
        // *********************************************
        //
        /// <summary>
        /// Called by an external thread to process an update request for one
        /// of our orders.
        /// </summary>
        /// <param name="orderUpdateReq"></param>
        /// <returns></returns>
        public virtual bool TryProcessOrderUpdateRequest(EventArgs orderUpdateReq)
        {
            bool isSuccess = false;

            if (orderUpdateReq is RequestEventArg <OrderRequestType> )
            {
                RequestEventArg <OrderRequestType> request = (RequestEventArg <OrderRequestType>)orderUpdateReq;
                InstrumentName  instrName = (InstrumentName)request.Data[0];
                OrderInstrument orderInstr;
                if (m_OrderInstruments.TryGetValue(instrName, out orderInstr))
                { // we found the order instrument
                    //orderInstr.ProcessRequest(request);
                    isSuccess = true;
                }
                else
                {
                    Log.NewEntry(LogLevel.Warning, "TryProcessOrderUpdateRequest: Order Instrument for {0} not found", instrName);
                }
                if (request.Data.Count > 3 && request.Data[3] is Order)    // this mean an order is attached to this request.
                {
                    m_OrderRecycleFactory.Recycle((Order)request.Data[3]); // recycle it here prior to recycling the request
                }
                m_OrderRequests.Recycle(request);                          // recycle all requests
            }
            return(isSuccess);
        }
        }// HubEventHandler()

        //
        //
        // *********************************************************************
        // ****                     Process Write Now()                     ****
        // *********************************************************************
        /// <summary>
        /// Force a write of the contents of the message queue to the output file now.
        /// </summary>
        private void ProcessFlushNow()
        {
            if (string.IsNullOrEmpty(this.FilePath) || m_WriteQueue.Count == 0)
            {
                return;
            }
            if (Log != null)
            {
                Log.NewEntry(LogLevel.Minor, "{0}.ProcessFlushNow: ", this.m_HubName);
            }
            try
            {
                using (System.IO.StreamWriter writer = new System.IO.StreamWriter(this.FilePath, true, Encoding.ASCII))
                {
                    DropQueueWriterEventArgs e;
                    while (m_WriteQueue.TryDequeue(out e))
                    {
                        writer.WriteLine(e.Message);
                        m_Factory.Recycle(e);
                    }
                    writer.Close();
                }//using StreamWriter
            }
            catch (Exception e)
            {
                if (Log != null)
                {
                    Log.NewEntry(LogLevel.Error, "{0}: Exception writing to drop file. {1}", this.m_HubName, e.Message);
                }
            }
        }// ProcessWriteNow().
Example #3
0
        //
        //
        #endregion//Constructors


        #region no Properties
        // *****************************************************************
        // ****                     Properties                          ****
        // *****************************************************************
        //
        //
        #endregion//Properties


        #region Public Methods
        // *****************************************************************
        // ****                     Public Methods                      ****
        // *****************************************************************
        //
        //
        //
        // *************************************************
        // ****             SendMessage()               ****
        // *************************************************
        /// <summary>
        /// Simple method to send a Message to a specific ServiceManager
        /// on a specific socket conversation.
        /// </summary>
        /// <param name="conversationId">Conversation to send message on, -1 means all conversations.</param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public bool SendMessage(int conversationId, Message msg)
        {
            string s = string.Format("{0}\n", Stringifiable.Stringify(msg, null, false));

            m_Messages.Recycle(msg);
            if (conversationId >= 0)
            {
                return(m_Socket.Send(s, conversationId));
            }
            else
            {
                return(m_Socket.Send(s));
            }
        }
Example #4
0
        //
        //
        #endregion//Constructors

        #region Hub Event Handler Overrides
        // *****************************************************************
        // ****                 Hub Event Handler                      ****
        // *****************************************************************
        //
        //
        //
        //
        // *******************************************************
        // ****                 HubEvent Handler              ****
        // *******************************************************
        protected override void HubEventHandler(EventArgs[] eventArgList)
        {
            foreach (EventArgs eventArg in eventArgList)
            {
                Type eArgType = eventArg.GetType();
                if (eArgType == typeof(DataHubRequest))
                {
                    DataHubRequest requestArg = (DataHubRequest)eventArg;
                    switch (requestArg.Request)
                    {
                    case RequestCode.ServiceStateChange:
                        // Process this!
                        break;

                    case RequestCode.Connect:
                        // Process this!
                        break;

                    case RequestCode.RequestProductsToRecord:
                        ProcessProductsToRecord(requestArg);
                        break;

                    default:
                        Log.NewEntry(LogLevel.Error, "HubEventHandler: DataHubRequest {0} not implemented", requestArg.ToString());
                        break;
                    }//switch(Request)
                    m_RequestFactory.Recycle(requestArg);
                }
                else if (eArgType == typeof(FoundServiceEventArg))
                {
                    ProcessFoundResources((FoundServiceEventArg)eventArg);
                }
                else if (eArgType == typeof(DatabaseWriterEventArgs))
                {
                    Log.NewEntry(LogLevel.Major, "Write Completed {0}", eArgType.ToString());
                }
                else if (eArgType == typeof(MarketStatusChangedEventArg))
                {
                    ProcessMarketStatusChangedEvent((MarketStatusChangedEventArg)eventArg);
                }
                else if (eArgType == typeof(DatabaseWriterHub.WriteStatusEventArgs))
                {
                    Log.NewEntry(LogLevel.Major, "Write Status {0}", eArgType.ToString());
                }
                else
                {   // unknown event.
                    Log.NewEntry(LogLevel.Error, "Unknown event type {0}", eArgType.ToString());
                }
            }
        }//end HubEvent
Example #5
0
        }// MarketInstrumentChanged()

        //
        //
        //
        //
        // *****************************************************
        // ****         Process Synthetic Order()           ****
        // *****************************************************
        /// <summary>
        /// Process fills from Strategy to PricingEngines.
        /// </summary>
        /// <param name="syntheticOrder"></param>
        /// <param name="newFills"></param>
        /// <returns>True if update required</returns>
        public virtual bool ProcessSyntheticOrder(SyntheticOrder syntheticOrder, List <Fill> newFills)
        {
            if (newFills == null || newFills.Count == 0)
            {
                return(false);
            }

            // Collect all fills into work spaces.
            Log.BeginEntry(LogLevel.Major, "Quote.ProcessSynthOrder: {0}  Fills=", ParentStrategy.Name);
            w_NewFills[0].Clear();
            w_NewFills[1].Clear();
            foreach (Fill fill in newFills)
            {
                int tradeSide = QTMath.MktSignToMktSide(fill.Qty);
                w_NewFills[tradeSide].Add(fill);
                m_BuySellQty[tradeSide] += fill.Qty;                // this records the raw fills as they come in.
                Log.AppendEntry(" [{0}]", fill);
            }
            int[] position = new int[2];                            // this will be updated during allocation of fills.
            m_Position.CopyTo(position, 0);
            Log.AppendEntry(". ");


            // Prepare entry for database write.
            DateTime localTime = ParentStrategy.StrategyHub.GetLocalTime();

            UV.Lib.DatabaseReaderWriters.Queries.FillsQuery query = new Lib.DatabaseReaderWriters.Queries.FillsQuery();

            // -----------------------------------------------------
            // Pass: distribute fills to stops
            // -----------------------------------------------------
            for (int tradeSide = 0; tradeSide < 2; ++tradeSide)
            {
                int exitingSide = QTMath.MktSideToActiveMktSide(tradeSide);
                if (w_NewFills[tradeSide].Count == 0 || m_FillQty[exitingSide].Count == 0)
                {
                    continue;
                }
                List <Quote> exitList = m_QuoteListRecycling.Get();      // get empty list.
                exitList.Clear();
                foreach (KeyValuePair <PricingEngine, int> kv in m_FillQty[exitingSide])
                {
                    Quote quote;
                    if (m_Quotes[tradeSide].TryGetValue(kv.Key, out quote) && quote.Reason == QuoteReason.Stop && quote.Qty != 0)
                    {
                        exitList.Add(quote);
                    }
                }
                if (exitList.Count > 0)
                {
                    Log.AppendEntry(" Distribute to {0} stop quoters:", exitList.Count);
                    DistributeFillsToQuoters(ref w_NewFills[tradeSide], ref exitList, ref query, ref w_DistributedFills, ref position);
                    Log.AppendEntry(". ");
                }
                exitList.Clear();
                m_QuoteListRecycling.Recycle(exitList);
            }//next tradeSide

            // -----------------------------------------------------
            // Pass: distribute fills to quoters who want them.
            // -----------------------------------------------------
            for (int tradeSide = 0; tradeSide < 2; ++tradeSide)
            {
                if (w_NewFills[tradeSide].Count == 0)
                {
                    continue;
                }
                int          exitingSide  = QTMath.MktSideToOtherSide(tradeSide);
                int          tradeSign    = QTMath.MktSideToMktSign(tradeSide);
                List <Quote> quotesToFill = m_QuoteListRecycling.Get();      // get empty lists for entry quotes.

                Log.AppendEntry(" Distribute to working quoters");
                List <int> iPriceKeys = new List <int>(m_QuotesByPrice[tradeSide].Keys);
                int        priceLevel = 0;
                while (w_NewFills[tradeSide].Count > 0 && priceLevel < iPriceKeys.Count)
                {
                    // On each interation, update our "pos" so we know the remaining qty.
                    int allowedEntryQty = tradeSign * Math.Max(0, m_MaxPosition - Math.Abs(position[tradeSide]));

                    // Load entry/exit quoters for this price level.
                    Log.AppendEntry(" lvl={0}/{1}:", priceLevel, iPriceKeys.Count);
                    quotesToFill.Clear();
                    List <Quote> quotes = null;
                    if (m_QuotesByPrice[tradeSide].TryGetValue(iPriceKeys[priceLevel], out quotes))
                    {
                        foreach (Quote quote in quotes)
                        {
                            if (quote.Qty != 0)
                            {
                                quotesToFill.Add(quote);
                            }
                        }
                    }

                    if (quotesToFill.Count > 0)
                    {
                        Log.AppendEntry(" Filling ({0}):", quotesToFill.Count);
                        DistributeFillsToQuoters(ref w_NewFills[tradeSide], ref quotesToFill, ref query, ref w_DistributedFills, ref position);
                    }

                    //
                    priceLevel++;
                }// next price level
                // Clean up.
                quotesToFill.Clear();
                m_QuoteListRecycling.Recycle(quotesToFill);
                Log.AppendEntry(" Finished.");
                if (w_NewFills[tradeSide].Count > 0)
                {
                    Log.AppendEntry(" {0} fills remaining.", w_NewFills[tradeSide].Count);
                }
                else
                {
                    Log.AppendEntry(" No fills remain.");
                }
            }//tradeSide

            // -----------------------------------------------------
            // Start emergency processing!
            // -----------------------------------------------------
            if (w_NewFills[0].Count > 0 || w_NewFills[1].Count > 0)
            {
                Log.AppendEntry(" Process unwanted fills!");
                ProcessUnwantedFills(ref w_NewFills, ref w_DistributedFills);
            }

            Log.EndEntry();                                             // end logging for us now, before we call other methods.
            // -----------------------------------------------------
            // Distribute these fills now.
            // -----------------------------------------------------
            if (query != null && query.Count != 0)
            {
                ParentStrategy.StrategyHub.RequestDatabaseWrite(query); // submit all the queries
            }
            foreach (KeyValuePair <Quote, List <Fill> > kv in w_DistributedFills)
            {
                int    fillQty   = 0;
                double fillPrice = 0;
                foreach (Fill fill in kv.Value)
                {
                    fillQty  += fill.Qty;
                    fillPrice = fill.Price;                             // TODO: this should be ave fill price
                }
                int tradeSide = QTMath.MktSignToMktSide(fillQty);
                int exitSide  = QTMath.MktSideToOtherSide(tradeSide);
                if (fillQty == 0)
                {
                    continue;
                }
                // Update our position counting.
                int openPos = 0;
                if (m_FillQty[exitSide].TryGetValue(kv.Key.PricingEngine, out openPos))
                {   // This is an exit (since this PricingEngine has open position on other side of mkt).
                    openPos += fillQty;


                    // Update real position table.
                    if (openPos * fillQty <= 0)
                    {
                        m_FillQty[exitSide].Remove(kv.Key.PricingEngine);// complete exit, possibly a side flip
                    }
                    if (openPos != 0)
                    {   // There is a new position (on other side of mkt).
                        int posSide = QTMath.MktSignToMktSide(openPos);
                        m_FillQty[posSide][kv.Key.PricingEngine] = openPos;
                    }
                }
                else
                {   // This is an entry!
                    // Update real position table.
                    if (m_FillQty[tradeSide].ContainsKey(kv.Key.PricingEngine))
                    {
                        m_FillQty[tradeSide][kv.Key.PricingEngine] += fillQty;  // add to this engines position.
                    }
                    else
                    {
                        m_FillQty[tradeSide].Add(kv.Key.PricingEngine, fillQty); // store this engines position.
                    }
                }
                // Trigger the pricing engine filled event!
                foreach (Fill fill in kv.Value)
                {
                    kv.Key.PricingEngine.Filled(fill);
                }
            }// next filled Quote.
            // Update total sum
            Log.BeginEntry(LogLevel.Major, "Quote.ProcessSynthOrder {0} Summary: ", ParentStrategy.Name);
            for (int tradeSide = 0; tradeSide < 2; tradeSide++)
            {
                // Add up the current position.
                int pos = 0;
                foreach (KeyValuePair <PricingEngine, int> kv in m_FillQty[tradeSide])
                {
                    pos += kv.Value;
                }
                m_Position[tradeSide] = pos;

                // Write some logging.
                Log.AppendEntry(" {0}-side:", QTMath.MktSideToLongString(tradeSide));
                Log.AppendEntry(" Pos={0:+0;-0;0}", m_Position[tradeSide]);
                foreach (KeyValuePair <PricingEngine, int> kv in m_FillQty[tradeSide])
                {
                    Log.AppendEntry(" [{1:+0;-0;0} {0}]", kv.Key.EngineName, kv.Value);
                }
                Log.AppendEntry(" TotalQty={0}", m_BuySellQty[tradeSide]);
                // Log undistributed fills too.
                if (m_UndistributedFills[tradeSide].Count > 0)
                {
                    Log.AppendEntry(" Undistributed {0}-fills:", QTMath.MktSideToLongString(tradeSide));
                    foreach (Fill fill in m_UndistributedFills[tradeSide])
                    {
                        Log.AppendEntry(" {0}", fill);
                    }
                }
            }// next tradeSide
            Log.AppendEntry(" |MaxPos|={0}.", m_MaxPosition);
            Log.EndEntry();

            //
            // Clean up work spaces
            //
            foreach (KeyValuePair <Quote, List <Fill> > kv in w_DistributedFills)
            {
                kv.Value.Clear();
                m_FillListRecycling.Recycle(kv.Value);
            }
            w_DistributedFills.Clear();                                 // Quoters and their fills to distribute.

            return(true);
        }// ProcessSyntheticOrder()