Пример #1
0
        //
        // ****             Serialize()            ****
        //
        private void Serialize()
        {
            // Create some books.
            StringBuilder msg = new StringBuilder();

            System.Random rand = new Random();
            for (int i = 0; i < 2; ++i)
            {
                InstrumentName name    = new InstrumentName(new Product("CME", "ED", ProductTypes.Spread), string.Format("#{0}", i + 1));
                double         minTick = 0.5;
                FillBookLifo   book    = new FillBookLifo(minTick, 12.50, name);
                for (int j = 0; j < 2; ++j)
                {
                    Fill aFill = Fill.Create();
                    aFill.Price        = rand.Next(20) * minTick;
                    aFill.Qty          = rand.Next(10) + 2;
                    aFill.LocalTime    = DateTime.Now.AddSeconds(-rand.NextDouble() * 100);
                    aFill.ExchangeTime = aFill.LocalTime;
                    book.Add(aFill);
                }
                m_FillBooks.Add(name, book);

                msg.AppendFormat("{0}", Stringifiable.Stringify(book));
            }// next i

            textBox1.Text = msg.ToString();
            this.Select();
        }// Serialize().
Пример #2
0
        //
        #endregion//Properties


        #region Public Methods
        // *****************************************************************
        // ****                     Public Methods                      ****
        // *****************************************************************
        //
        //
        //
        // ****                     Add()                       ****
        //
        /// <summary>
        /// Method:
        ///     if (qty*NetPosition) >= 0 we are simply added to position.
        ///     else
        ///         while (qty!=0 and Fills.Count > 0)
        ///             if (LastFill.Qty+qty)*qty >= 0 we cancel this entire fill, remove it,
        ///                 and have left over qty += LastFill.Qty (qty may be exactly zero).
        ///             else LastFill.Qty += qty, and LastFill.Qty is not zero, qty=0.
        ///         if (qty!=0) we have completely flipped our position to other side.  Add new fill.
        /// </summary>
        /// <param name="aFill">A ref to the Fill is kept here.</param>
        public virtual void Add(Fill aFill)
        {
            int remainingQty = aFill.Qty;

            if (remainingQty == 0)
            {
                return;     // do nothing in this case.
            }
            // Store the fill.
            if (aFill.LocalTime.CompareTo(LocalTimeLast) > 0)
            {
                LocalTimeLast = aFill.LocalTime;
            }
            if (aFill.ExchangeTime.CompareTo(ExchangeTimeLast) > 0)
            {
                ExchangeTimeLast = aFill.ExchangeTime;
            }
            m_FillTrail.Add(aFill);

            // Update total volume
            m_Volume += Math.Abs(remainingQty);

            //
            // Allocate fill against our open posiion.
            //
            if (m_FillsOpen.Count == 0 || remainingQty * m_FillsOpen[0].Qty >= 0)
            {   // adding to our position, or new position.
                Fill newFill = Fill.Create(aFill);
                m_FillsOpen.Add(newFill);
            }
            else
            {   // cancelling positions.
                double realPnL = 0.0;
                while (remainingQty != 0 && m_FillsOpen.Count > 0)
                {
                    Fill oldFill = m_FillsOpen[m_FillsOpen.Count - 1];
                    if ((oldFill.Qty + remainingQty) * remainingQty >= 0)
                    {                                                                             // Incoming qty kills old fill qty "Q0" entirely; so the transacting amount is Q0
                        realPnL      += -oldFill.Qty * oldFill.Price + oldFill.Qty * aFill.Price; // -Q0*P0 - (-Q0)*P
                        remainingQty += m_FillsOpen[m_FillsOpen.Count - 1].Qty;                   // Q = Q + Q0
                        m_FillsOpen.RemoveAt(m_FillsOpen.Count - 1);                              // remove entire old fill [P0,Q0]
                    }
                    else
                    {                                                                             // Old fill completely absorbs new fill qty "Q"; transacting amount is Q
                        realPnL     += remainingQty * oldFill.Price - remainingQty * aFill.Price; // -pnl = -(-Q)*P1 - Q*P
                        oldFill.Qty += remainingQty;                                              // reduce oldQty by amount transacted.
                        remainingQty = 0;                                                         // there is no quantity left.
                    }
                }
                if (remainingQty != 0)
                {                               // After cancelling out all levels of old fills, we still have some left!
                    Fill newFill = Fill.Create(aFill);
                    newFill.Qty = remainingQty; // overwrite the quantity with remaining qty.
                    m_FillsOpen.Add(newFill);
                }
                m_RealizedGain += realPnL;
            }
            UpdatePositionInfo();
        }//Add()
Пример #3
0
        private void Test1()
        {
            InstrumentName name = new InstrumentName(new Product("CME", "GE", ProductTypes.Spread), "H2M2");
            FillBookLifo   book = new FillBookLifo(0.5, 12.50, name);

            List <Fill> aList = new List <Fill>();

            for (int i = 0; i < 2; ++i)
            {
                Fill aFill = Fill.Create();
                aFill.Qty          = i + 2;
                aFill.Price        = 1.0 + 0.5 * i;
                aFill.LocalTime    = DateTime.Now.AddHours(i * .25);
                aFill.ExchangeTime = aFill.LocalTime;
                aList.Add(aFill);
                //string s = SerializeToString(aFill).Replace('\n',' ');
                //textBox1.Text = textBox1.Text + s;
                book.Add(aFill);
            }
            textBox1.Text = SerializeToString(book);
        }
Пример #4
0
 public static Tensor <T> Const <T>(Scalar <T> content, params Dim[] shape) =>
 Fill <T> .Create(content, shape);
Пример #5
0
        }//DistributeFillsToQuoters()

        //
        //
        // *************************************************************
        // ****             Process Unwanted Fills()                ****
        // *************************************************************
        protected void ProcessUnwantedFills(ref List <Fill>[] newFills, ref Dictionary <Quote, List <Fill> > distributedFills)
        {
            //
            // Cancel off-setting fills.
            //
            if (newFills[0].Count > 0 && newFills[1].Count > 0)
            {
                Log.AppendEntry(" Remove offsetting fills:");
                while (newFills[0].Count > 0 && newFills[1].Count > 0)
                {
                    Fill fillLong = newFills[0][0];
                    newFills[0].RemoveAt(0);
                    Fill fillShort = newFills[1][0];
                    newFills[1].RemoveAt(0);
                    int netQty       = fillLong.Qty + fillShort.Qty; // cancel the first fill in each list.
                    int cancelledQty = Math.Min(Math.Abs(fillLong.Qty), Math.Abs(fillShort.Qty));
                    Log.AppendEntry(" PnL={0}", cancelledQty * (fillShort.Price - fillLong.Price));
                    if (netQty > 0)
                    {   // Long side will survive somewhat.
                        Fill remainder = Fill.Create(fillLong);
                        remainder.Qty = netQty;
                        newFills[0].Insert(0, remainder);
                    }
                    else if (netQty < 0)
                    {
                        Fill remainder = Fill.Create(fillShort);
                        remainder.Qty = netQty;
                        newFills[1].Insert(0, remainder);
                    }
                }
            }

            //
            // Pass: distribute fills to anyone with position: "forced exit"
            //
            if (newFills[0].Count > 0 || newFills[1].Count > 0)
            {
                for (int tradeSide = 0; tradeSide < 2; ++tradeSide)
                {
                    int exitSide = QTMath.MktSideToOtherSide(tradeSide);
                    if (newFills[tradeSide].Count == 0 || m_FillQty[exitSide].Count == 0)
                    {
                        continue;
                    }
                    int tradeSign = QTMath.MktSideToMktSign(tradeSide);
                    foreach (KeyValuePair <PricingEngine, int> kv in m_FillQty[exitSide])
                    {
                        Quote       quote;
                        List <Fill> fills;
                        int         qtyToForce = 0;
                        if (m_Quotes[tradeSide].TryGetValue(kv.Key, out quote) && distributedFills.TryGetValue(quote, out fills))
                        {   // This strategy already has some fills.
                            int fillQty = 0;
                            foreach (Fill fill in fills)
                            {
                                fillQty += fill.Qty;
                            }
                            int finalQty = (kv.Value + fillQty);
                            qtyToForce = Math.Min(0, tradeSign * finalQty); // qty for fill he can still take.
                        }
                        else
                        {
                            qtyToForce = -kv.Value;
                        }
                        if (qtyToForce != 0)
                        {   // Pass to him extra fills
                            foreach (Fill fill in newFills[tradeSide])
                            {
                            }
                        }
                    }
                }// next side
            }

            //
            // Pass: distribute fills to anyone with a quote!
            //
            if (newFills[0].Count > 0 || newFills[1].Count > 0)
            {
                for (int tradeSide = 0; tradeSide < 2; ++tradeSide)
                {
                    if (newFills[tradeSide].Count == 0)
                    {
                        continue;
                    }
                    Log.AppendEntry(" Forcing fills:");
                    int tradeSign = QTMath.MktSideToMktSign(tradeSide);
                    // Collect all the quotes
                    List <Quote> quotes = m_QuoteListRecycling.Get();
                    quotes.Clear();
                    foreach (KeyValuePair <int, List <Quote> > kv in m_QuotesByPrice[tradeSide])
                    {
                        quotes.AddRange(kv.Value);
                    }
                    int quoteID    = 0;
                    int qtyToForce = 1;                             // TODO: This can be dynamic
                    // Force fills now
                    while (newFills[tradeSide].Count > 0 && quotes.Count > 0)
                    {
                        Quote quote    = quotes[quoteID];
                        Fill  origFill = newFills[tradeSide][0];
                        newFills[tradeSide].RemoveAt(0);

                        Fill fillToDistribute = null;
                        int  fillQty          = tradeSign * Math.Min(qtyToForce, Math.Abs(origFill.Qty));
                        if ((origFill.Qty - fillQty) == 0)
                        {   // Entire fill is consumed.
                            fillToDistribute = origFill;
                        }
                        else
                        {
                            fillToDistribute     = Fill.Create(origFill);
                            fillToDistribute.Qty = fillQty;
                            Fill remainingFill = Fill.Create(origFill);
                            remainingFill.Qty = origFill.Qty - fillQty;
                            newFills[tradeSide].Insert(0, remainingFill);
                        }
                        List <Fill> fills;
                        if (!distributedFills.TryGetValue(quote, out fills))
                        {   // This is this quotes first fill, so create a fill list.
                            fills = new List <Fill>();
                            distributedFills.Add(quote, fills);
                        }
                        fills.Add(fillToDistribute);
                        Log.AppendEntry(" {0} filled {1}.", quote.PricingEngine.EngineName, fillToDistribute);
                        // increment the while loop!
                        quoteID = (quoteID + 1) % quotes.Count;
                    }//wend
                    // Cleanup.
                    quotes.Clear();
                    m_QuoteListRecycling.Recycle(quotes);
                } // next side
            }     // if fills to distribute.


            //
            // Failed to distribute fills.
            //
            if (newFills[0].Count > 0 || newFills[1].Count > 0)
            {
                Log.AppendEntry(" FAILED to distribute fills:");
                for (int tradeSide = 0; tradeSide < 2; ++tradeSide)
                {
                    foreach (Fill fill in newFills[tradeSide])
                    {
                        m_UndistributedFills[tradeSide].Add(fill);
                        Log.AppendEntry(" {0}", fill);
                    }
                }
            }
        }// ProcessUnwantedFills()
Пример #6
0
        }// ProcessSyntheticOrder()

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


        #region Private Methods
        // *****************************************************************
        // ****                     Private Methods                     ****
        // *****************************************************************
        //
        //
        //
        //
        //
        // *********************************************************************
        // ****                 DistributeFillsToQuoters()                  ****
        // *********************************************************************
        /// <summary>
        /// This distibutes fills in the list to those quotes provided in the list quotes.
        /// In the process of distrubuting, the fills are removed from the first list, and the
        /// quote quantities are reduced.  PricingEngines that will receive the fills are
        /// added to the "distributedFills" dictionary.  Also, the net position[] array is updated and
        /// fill messages are added to the query.
        /// </summary>
        /// <param name="fillsToDistribute">fills that will be distributed</param>
        /// <param name="quotes">quotes that will be distributed to.</param>
        /// <param name="query"></param>
        /// <param name="distributedFills"></param>
        /// <param name="position"></param>
        protected void DistributeFillsToQuoters(ref List <Fill> fillsToDistribute, ref List <Quote> quotes,
                                                ref FillsQuery query, ref Dictionary <Quote, List <Fill> > distributedFills, ref int[] position)
        {
            DateTime localTime = ParentStrategy.StrategyHub.GetLocalTime();
            int      quoter    = 0;

            while (quoter < quotes.Count && fillsToDistribute.Count > 0)// loop thru each quoter until fills gone.
            {
                Quote quote = quotes[quoter];
                Log.AppendEntry(" [{0}]", quote);
                Fill fill = fillsToDistribute[0]; // consider first fill.
                if (fill.Qty == 0)
                {                                 // this should never happen.
                    Log.AppendEntry(" Removed empty fill {0}.", fill);
                    fillsToDistribute.Remove(fill);
                    continue;
                }
                int tradeSign = Math.Sign(fill.Qty);
                int tradeSide = QTMath.MktSignToMktSide(tradeSign);

                //
                // Determine how much to allocate to this quoter.
                //
                Fill allocatedFill = null;     // fill to allocate to quoter.
                int  remainingQty  = fill.Qty; // qty to be added back to fills list.
                if (quote.Side != tradeSide)
                {                              // This is an error.  Never allocate a fill to a quote for the other side of mkt!
                    Log.AppendEntry(" wrong-side {0}.", QTMath.MktSideToLongString(quote.Side));
                }
                //else if (forceFillAbsQty != 0)
                //{   // Here, we are forcing fills to be allocated even to quoters who have qty = 0.
                //    remainingQty = tradeSign * Math.Max(0, Math.Abs(fill.Qty) - forceFillAbsQty); // force up to full qty.
                //}
                else if (quote.Reason != QuoteReason.Entry && quote.Qty != 0)
                {   // Normal non-entry request. Try to fill this quote as much as possible completely.
                    remainingQty = tradeSign * Math.Max(0, (fill.Qty - quote.Qty) * tradeSign);
                    Log.AppendEntry(" taking {0}, remaining {1},", quote.Qty, remainingQty);
                }
                else if (quote.Reason == QuoteReason.Entry && quote.Qty != 0)
                {   // Normal entry request.  Don't allow entries to violet position limit!
                    int allowedEntryQty = tradeSign * Math.Max(0, m_MaxPosition - Math.Abs(position[tradeSide]));
                    //remainingQty = tradeSign * Math.Max(0, (allowedEntryQty - quote.Qty) * tradeSign);
                    int qtyWeCanTake = Math.Min(Math.Abs(allowedEntryQty), Math.Abs(quote.Qty)) * tradeSign;
                    remainingQty = tradeSign * Math.Max(0, (fill.Qty - qtyWeCanTake) * tradeSign);
                    Log.AppendEntry(" taking {0}, remaining {1},", qtyWeCanTake, remainingQty);
                }

                //
                // Allocate the fill
                //
                if (remainingQty == 0)
                {                                   // This fill is completely consumed by the quoter.
                    fillsToDistribute.Remove(fill); // remove fill from list.
                    allocatedFill = fill;
                }
                else if (remainingQty == fill.Qty)
                {   // No qty was consumed at all!?!
                    allocatedFill = null;
                }
                else
                {                                   // This fill is only partially consumed.
                    fillsToDistribute.Remove(fill); // remove original fill from list.
                    Fill remainingFill = Fill.Create(fill);
                    remainingFill.Qty = remainingQty;
                    fillsToDistribute.Insert(0, remainingFill);         // First, replace the unused portion back onto list.

                    allocatedFill     = Fill.Create(fill);
                    allocatedFill.Qty = fill.Qty - remainingQty;        // Allocate the consumed portion.
                }
                if (allocatedFill != null && allocatedFill.Qty != 0)
                {
                    Log.AppendEntry(" filled {1}.", quote.PricingEngine.EngineName, allocatedFill);
                    List <Fill> fills;
                    if (distributedFills.TryGetValue(quote, out fills) == false)
                    {   // No fills had be distributed to this quote previously.
                        fills = m_FillListRecycling.Get();
                        fills.Clear();
                        distributedFills.Add(quote, fills);
                    }
                    fills.Add(allocatedFill);
                    position[quote.Side] += allocatedFill.Qty;
                    quote.Qty             = tradeSign * Math.Max(0, tradeSign * (quote.Qty - allocatedFill.Qty));
                    string msgStr = quote.FillAttribution();
                    query.AddItemToWrite(ParentStrategy.SqlId, -1, localTime, m_Services.User, quote.PricingEngine.EngineName, msgStr, allocatedFill.Qty, allocatedFill.Price);
                }
                else
                {
                    Log.AppendEntry(" skipped.");
                }
                quoter++;                  // otherwise move to next quoter
            }// next quoter
        }//DistributeFillsToQuoters()