Example #1
0
        }// CreatePropertyInventory()

        //
        private void FindNewProperties(object o)
        {
            Type type = o.GetType();

            PropertyInfo[] propertyInfo = type.GetProperties();
            Log.BeginEntry(LogLevel.Minor, "FillBookView: Found columns : ");
            foreach (PropertyInfo info in propertyInfo)
            {
                bool isGood = true;
                isGood = isGood && info.CanRead;
                Type propType = info.PropertyType;
                isGood = isGood && (!propType.IsClass);

                if (isGood && !m_PropertyNames.Contains(info.Name))
                {
                    m_PropertyNames.Add(info.Name);
                    if (propType == typeof(DateTime))
                    {
                        m_PropertyFormat.Add("{0:dd-mm-yyyy hh:MM:ss}");
                    }
                    else
                    {
                        m_PropertyFormat.Add("{0}");
                    }
                    Log.AppendEntry("{0}({1}) ", info.Name, propType.ToString());
                }
            }
            Log.EndEntry();
        } //FindNewProperties()
Example #2
0
        }//StopThread()

        //
        //
        //
        //
        private void WriteFillToLog(string fillEventName, Fill fill)
        {
            if (Log != null && Log.BeginEntry(LogLevel.Minor, "FillListener: {0} {1} ", this, fillEventName))
            {
                Log.AppendEntry("[InstrumentKey={0}]", fill.InstrumentKey.ToString());
                Log.AppendEntry("[{0} {1}@{2}]", Enum.GetName(typeof(BuySell), fill.BuySell), fill.Quantity.ToString(), fill.MatchPrice.ToDouble());

                System.Reflection.PropertyInfo[] properties = fill.GetType().GetProperties();

                // Non flags
                foreach (System.Reflection.PropertyInfo aProperty in properties)
                {
                    Type type = aProperty.PropertyType;
                    if (aProperty.CanRead && type != typeof(System.Boolean))
                    {
                        object o = aProperty.GetValue(fill);
                        if (o is DateTime)
                        {
                            Log.AppendEntry("[{0}={1}]", aProperty.Name, ((DateTime)o).ToString(Misty.Lib.Utilities.Strings.FormatDateTimeZone));
                        }
                        else if (!string.IsNullOrEmpty(o.ToString()))
                        {
                            Log.AppendEntry("[{0}={1}]", aProperty.Name, o);
                        }
                    }
                }

                // Show flags
                Log.AppendEntry("[Flags");
                foreach (System.Reflection.PropertyInfo aProperty in properties)
                {
                    Type type = aProperty.PropertyType;
                    if (aProperty.CanRead && type == typeof(System.Boolean) && (bool)aProperty.GetValue(fill))
                    {
                        Log.AppendEntry(" {0}", aProperty.Name);        // if true, add name.
                    }
                }
                Log.AppendEntry("]");
                Log.EndEntry();
            }
        }// WriteFillToLog()
        private List <MarketDataItem[]> m_HistoricLegMarkets = null;        // markets for each leg, one-to-one with HistoricDateTime
        //
        // *****************************************************
        // ****             Request Historic Data()         ****
        // *****************************************************
        /// <summary>
        /// This is a utility call
        /// </summary>
        /// <param name="startLocal">starting time for data in local time zone</param>
        /// <param name="endLocal">ending time for data range</param>
        protected void RequestHistoricData(DateTime startLocal, DateTime endLocal)
        {
            DateTime     startUTC   = startLocal.ToUniversalTime();
            DateTime     endUTC     = endLocal.ToUniversalTime();
            const double round      = 10.0;
            double       rangeHours = Math.Round(round * (endUTC.Subtract(startUTC)).TotalHours) / round;

            Log.BeginEntry(LogLevel.Minor, "PricingEngine.RequestHistoricData: {0} requesting {1} hours for", this.ParentStrategy.Name, rangeHours);
            foreach (PriceLeg pricingLeg in m_Legs)
            {
                Log.AppendEntry(" {0}", pricingLeg.InstrumentName);
                ParentStrategy.StrategyHub.RequestHistoricData(pricingLeg.InstrumentName, startUTC, endUTC, this.AcceptHistoricData, this.ParentStrategy);
            }
            Log.EndEntry();
        }//RequestHistoricData()
Example #4
0
        }//listBoxProducts_SelectedIndexChanged()

        /// <summary>
        /// When the selected future instrument changes, it subscribes to the price for that instrument and also its spread components.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void listBoxInstruments_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Wait the response from above and check which spread instruments are desired using boot-strapping method.
            string         selectedInstrument = listBoxInstruments.SelectedItem.ToString();
            InstrumentName selectedInstrumentName;

            // Found the spread components for the selected future instrument, which is normally in the long term.
            if (!m_FutureInstruments.TryGetValue(selectedInstrument, out selectedInstrumentName))
            {
                Log.NewEntry(LogLevel.Warning, "Can not find selected instrument.");
                return;
            }

            // Firstly, subscribe to the price of that instrument.
            if (m_MarketTTAPI.RequestInstrumentSubscription(selectedInstrumentName))
            {
                m_MarketReadTimer.Stop();
                m_MarketReadTimer.Start();
                Log.NewEntry(LogLevel.Minor, "Successfully send trade price subscription for instrument {0}.", selectedInstrumentName.FullName);
            }
            else
            {
                Log.NewEntry(LogLevel.Warning, "Failed to send trade price subscription for instrument {0}.", selectedInstrumentName.FullName);
            }

            // Then construct the spread in the path and subscribe to the prices for the spread instrument components.
            ExpiryPoint startPoint = new ExpiryPoint(14, 3);
            ExpiryPoint endPoint   = null;

            if (!BootStrappingRule.TryExtractExpiryYearMonth(selectedInstrumentName.SeriesName, out endPoint))
            {
                Log.NewEntry(LogLevel.Warning, "Failed to get the expiry point for future instrument {0}.", selectedInstrumentName);
                return;
            }
            else
            {
                Log.NewEntry(LogLevel.Minor, "Start bootstrapping algorithm for instrument {0}.", selectedInstrumentName);
                List <ExpiryPoint>         expirySeries       = null;
                List <List <ExpiryPoint> > spreadCombinations = null;

                // Expiry series only contains a limited number of expiry points.
                if (BootStrappingRule.GetExpirySeriesForProduct(m_FutureInstruments, out expirySeries))
                {
                    // Output the spread combinations by our algorithm under maximum step.
                    if (BootStrappingRule.TryGetAllPathsByEnumeration(startPoint, endPoint, expirySeries, 5, out spreadCombinations))
                    {
                        Log.BeginEntry(LogLevel.Minor, "Start bootstrapping enumeration:");
                        foreach (List <ExpiryPoint> row in spreadCombinations)
                        {
                            foreach (ExpiryPoint point in row)
                            {
                                Log.AppendEntry(point.ToString());
                                Log.AppendEntry(" ");
                            }
                            Log.AppendEntry("\r\n");
                        }
                        Log.EndEntry();
                        Log.NewEntry(LogLevel.Minor, "Successfully completes enumeration algorithm.");
                    }
                    else
                    {
                        Log.NewEntry(LogLevel.Warning, "There is problem in getting path combinations");
                        return;
                    }
                }
                else
                {
                    Log.NewEntry(LogLevel.Warning, "There is problem in getting expiry series");
                    return;
                }

                // Try to load product spread information table and construct the spread names that we need.
                string productName = selectedInstrumentName.Product.ProductName;
                List <List <string> > spreadNameGeneratedCombinations = null;
                if (m_CSVSpreadInfoReader.TryDetectProductName(productName))
                {
                    string firstDelimiter;
                    string secondDelimiter;
                    m_CSVSpreadInfoReader.TryGetFirstDateDelimiter(productName, out firstDelimiter);
                    m_CSVSpreadInfoReader.TryGetSecondDateDelimiter(productName, out secondDelimiter);

                    // Use the spread info reader to construct the names for the spread instruments in all paths.
                    if (!TryGenerateSpreadInstrumentNamesInAllPaths(firstDelimiter, secondDelimiter, spreadCombinations, out spreadNameGeneratedCombinations))
                    {
                        Log.NewEntry(LogLevel.Warning, "Failed to generate spread names for all paths");
                        return;
                    }
                    else
                    {
                        // Output the spread names for all paths to log viewer.
                        Log.BeginEntry(LogLevel.Minor);
                        foreach (List <string> spreadNameEachPath in spreadNameGeneratedCombinations)
                        {
                            foreach (string spreadName in spreadNameEachPath)
                            {
                                Log.AppendEntry(spreadName);
                                Log.AppendEntry(" ");
                            }
                            Log.AppendEntry("\r\n");
                        }
                        Log.EndEntry();
                        Log.NewEntry(LogLevel.Minor, "Successfully generate spread names for all paths.");
                    }
                }
                else
                {
                    Log.NewEntry(LogLevel.Warning, "There is no entry for the product of {0} in the csv file", productName);
                    return;
                }

                // Try to match the generated names with what we have downloaded from the TT.
                // Pull a valid path and subscribe to the prices for the spread components in that path.
                int startPathIndex = 0;
                if (!TryPullSpreadInstruments(startPathIndex, spreadNameGeneratedCombinations, out m_InstrumentSubscriptions))
                {
                    Log.NewEntry(LogLevel.Warning, "There is problem in pulling tt spread instruments");
                    return;
                }
                else
                {
                    // This block subscribes to the inside market price for the spread instruments.
                    foreach (InstrumentName instrumentName in m_InstrumentSubscriptions)
                    {
                        if (m_MarketTTAPI.RequestInstrumentSubscription(instrumentName))
                        {
                            Log.NewEntry(LogLevel.Minor, "Successfully send trade price subscription for instrument {0}.", instrumentName.FullName);
                        }
                        else
                        {
                            Log.NewEntry(LogLevel.Warning, "Failed to send trade price subscription for instrument {0}.", instrumentName.FullName);
                        }
                    }
                }
            }
        }//listBoxInstruments_SelectedIndexChanged()
        }// ProcessCopyTo()

        //
        //
        //
        /// <summary>
        /// Copies all files in the local Path (that match a given filename pattern) to
        /// another path.
        /// </summary>
        /// <param name="eventArgs"></param>
        private void ProcessCopyAllFiles(DropQueueWriterEventArgs eventArgs)
        {
            // Create name for archival file.
            string archiveDirPath;

            if (eventArgs.Message2.Length == 0)
            {
                m_Factory.Recycle(eventArgs);
                return;                                                 // User must provide a target DirPath!
            }
            else
            {
                if (eventArgs.Message2[eventArgs.Message2.Length - 1].Equals('\\')) // .EndsWith("\\"))
                {
                    archiveDirPath = eventArgs.Message2.ToString();                 // user provided a target path
                }
                else
                {
                    archiveDirPath = string.Format("{0}\\", eventArgs.Message2);
                }
            }
            try
            {
                if (!IsDirectoryExists(archiveDirPath)) // Confirm target directory exists.
                {                                       // Cannot find/create target directory.
                    if (Log != null)
                    {
                        Log.NewEntry(LogLevel.Major, "{1}: Failed to copy all files to {0}.  Failed to find/create that directory.", archiveDirPath, this.m_HubName);
                    }
                    m_Factory.Recycle(eventArgs);
                    return;                                             // nothing we can do but quit.
                }
                // Get Local filenames to copy.
                List <string> fileNamesWeCopied = new List <string>();
                string[]      localFileNameArray;
                if (eventArgs.Message.Length > 0)                      // pattern provided in ".FileName" property
                {
                    localFileNameArray = System.IO.Directory.GetFiles(this.m_PathName, eventArgs.Message.ToString());
                }
                else
                {
                    localFileNameArray = System.IO.Directory.GetFiles(this.m_PathName);// no pattern provided.
                }
                foreach (string s in localFileNameArray)
                {
                    string fileName        = s.Substring(s.LastIndexOf('\\') + 1);                  // local file name.
                    string archiveFilePath = string.Format("{0}{1}", archiveDirPath, fileName);     // archive file path
                    try
                    {
                        if (System.IO.File.Exists(archiveFilePath))
                        {   // This file already exists in the output directory.
                            System.IO.FileInfo infoRemote = new System.IO.FileInfo(archiveFilePath);
                            System.IO.FileInfo infoLocal  = new System.IO.FileInfo(s);
                            if (infoLocal.Length > infoRemote.Length)
                            {   // The local file is bigger, so we better do the copy!
                                if (Log != null)
                                {
                                    Log.NewEntry(LogLevel.Major, "{1}.ProcessCopyAllFiles: Local copy of {0} is larger than remote, so we will copy to remote.", fileName, this.m_HubName);
                                }
                                System.IO.File.Copy(s, archiveFilePath, true);
                                fileNamesWeCopied.Add(fileName);
                            }
                        }
                        else
                        {   // File doesn't already exist, so just copy it.
                            System.IO.File.Copy(s, archiveFilePath, true);
                            fileNamesWeCopied.Add(fileName);
                        }
                    }
                    catch (Exception e)
                    {
                        if (Log != null)
                        {
                            Log.NewEntry(LogLevel.Major, "{1}.ProcessCopyAllFiles: Failed to copy file to {0}.  Exception {2}.", archiveDirPath, this.m_HubName, e.Message);
                        }
                    }
                }
                // Report our results
                if (Log != null && Log.BeginEntry(LogLevel.Minor))
                {
                    Log.AppendEntry("{1}.ProcessCopyAllFiles: Copied {0} files [", fileNamesWeCopied.Count, this.m_HubName);
                    foreach (string s in fileNamesWeCopied)
                    {
                        Log.AppendEntry(" {0}", s);
                    }
                    Log.AppendEntry("].");
                    Log.EndEntry();
                }
            }
            catch (Exception e)
            {
                if (Log != null)
                {
                    Log.NewEntry(LogLevel.Major, "{2}: Copying all files from {0} to {1} failed. Exception: {2}", this.FilePath, archiveDirPath, e.Message, this.m_HubName);
                }
            }
            // Exit
            m_Factory.Recycle(eventArgs);
        }// ProcessCopyAllFiles()
Example #6
0
        //
        //
        #endregion//Constructors



        #region Public Methods
        // *****************************************************************
        // ****                     Public Methods                      ****
        // *****************************************************************
        //
        //
        /// <summary>
        /// <param name="outDirPath">Local directory containing synched files to compare, string.Format("{0}{1}", m_AppInfo.UserPath, "Statements\\");</param>
        /// <param name="localFileNamesCopied">Full path names of any new files found on ftp site, null if method is false.</param>
        /// <returns>true, if attempt was successful, but if no new files were found, localFileNamesCopied.Count = 0.</returns>
        /// </summary>
        public bool TryCopyNewRemoteFilesToLocal(string FTPUserName, string outDirPath, out List <string> localFileNamesCopied, string FTPKeyPath)
        {
            localFileNamesCopied = null;                            // filepaths that were copied locally to out directory.
            if (!TryInitialize(FTPKeyPath))                         // Prepare for ftp connection.
            {
                return(false);
            }

            // Get list of files on ftp server.
            List <SftpFile> ftpFileList = null;

            if (!TryGetRemoteFileNames(FTPUserName, out ftpFileList))
            {
                return(false);
            }

            // Read local files.
            if (!System.IO.Directory.Exists(outDirPath))
            {
                try
                {
                    System.IO.Directory.CreateDirectory(outDirPath);
                }
                catch (Exception ex)
                {
                    if (Log != null)
                    {
                        Log.NewEntry(LogLevel.Error, "FtpReader: Cannot find statement directory {0}.  Exception {1}", outDirPath, ex.Message);
                    }
                    return(false);
                }
            }
            List <string> localFileList = new List <string>();

            string[] fileName = System.IO.Directory.GetFiles(outDirPath);
            foreach (string s in fileName)
            {
                int nPtr = s.LastIndexOf('\\');
                localFileList.Add(s.Substring(nPtr + 1, s.Length - (nPtr + 1)));            // keep file name only.
            }

            //
            // Determine files we are missing.
            //
            List <SftpFile> filesWeWant = new List <SftpFile>();

            if (Log != null)
            {
                Log.BeginEntry(LogLevel.Minor, "FtpReader: Discovered");
            }
            foreach (SftpFile ftpFile in ftpFileList)                                       // loop thru files on ftp server...
            {
                string ftpFileName      = ftpFile.Name;
                bool   isFileOfInterest = true;
                if (isFileOfInterest && m_FilePatterns.Length > 0)                          // test filename prefix.
                {
                    isFileOfInterest = false;
                    foreach (string prefix in m_FilePatterns)
                    {
                        isFileOfInterest = isFileOfInterest || ftpFileName.ToUpper().Contains(prefix);
                    }
                }
                if (isFileOfInterest && m_FileNameSuffixes.Length > 0)                      // test filename suffix
                {
                    isFileOfInterest = false;
                    foreach (string suffix in m_FileNameSuffixes)
                    {
                        isFileOfInterest = isFileOfInterest || ftpFileName.EndsWith(suffix, StringComparison.CurrentCultureIgnoreCase);
                    }
                }
                if (isFileOfInterest && !localFileList.Contains(ftpFileName))
                {
                    if (Log != null)
                    {
                        Log.AppendEntry(" {0}", ftpFile.Name);
                    }
                    filesWeWant.Add(ftpFile);
                }
            }// next ftpFile
            if (Log != null)
            {
                Log.AppendEntry(" {0} files.", filesWeWant.Count);
                Log.EndEntry();
            }

            // Tries to copy the files in filesWeWant.
            TryCopyFilesWeWant(FTPUserName, filesWeWant, outDirPath, out localFileNamesCopied);



            if (Log != null)
            {
                Log.NewEntry(LogLevel.Minor, "FtpReader: Finished getting all files.");
            }
            return(true);
        } // TryCopyNewFilesToLocal()
Example #7
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()
Example #8
0
        //
        #endregion//Public Methods



        #region Private Methods
        // *****************************************************************
        // ****						Private Methods						****
        // *****************************************************************
        //
        //
        //
        //
        // ****                 Update Stop Levels()                ****
        //
        /// <summary>
        /// This updates the list of stop-levels each time there is a fill.
        /// </summary>
        /// <param name="signedQty"></param>
        /// <param name="fillPrice"></param>
        /// <param name="preFillPosition"></param>
        protected virtual void UpdateNewFill(int signedQty, double fillPrice, int preFillPosition)
        {
            m_IsStopTriggered = false; // reset this
            if (preFillPosition * signedQty >= 0)
            {                          // New fill is adding to our current position (or no previous position).
                // Calculate new stopping level associated with this fill.
                double pStop = fillPrice - Math.Sign(signedQty) * m_StopBase * m_StopBaseMultiplier;
                if (m_StopPriceList.Contains(pStop))// stop book already contains this price level.
                {
                    m_StopPriceQty[pStop] += signedQty;
                }
                else
                {
                    m_StopPriceQty.Add(pStop, signedQty);
                    m_StopPriceList.Add(pStop);
                }
                m_StopPriceList.Sort();             // keep this list sorted.
            }
            else
            {   // New fill is decreasing our position (or we've completely flipped to other side).
                // In this case, we know that signedQty and quantities in stop list have opposite signs.
                // Remove stops starting at the closest:
                // That means, for long position, we are interested in LARGEST stop price levels, etc.
                int qtyToRemove = -signedQty;          // if we sold -5, then qtyToRemove is +5, same sign as position!
                int level       = (m_StopPriceList.Count - 1) * (Math.Sign(qtyToRemove) + 1) / 2;
                m_PriceToDelete.Clear();
                while (qtyToRemove != 0 && level >= 0 && level < m_StopPriceList.Count)
                {
                    double price  = m_StopPriceList[level];
                    int    qty    = m_StopPriceQty[price];
                    int    qtyMin = Math.Sign(qty) * Math.Min(Math.Abs(qty), Math.Abs(qtyToRemove));
                    qty         -= qtyMin;              // remove qty from list
                    qtyToRemove -= qtyMin;              // remove for outstanding qty to remove.

                    if (qty == 0)
                    {
                        m_PriceToDelete.Add(price);   // remove zero qty entries, remove from StopPriceList outside loop!
                    }
                    else
                    {
                        m_StopPriceQty[price] = qty;
                    }
                    // change the counter
                    level += Math.Sign(signedQty);      // pos long --> decrease level counter, etc.
                }//while
                // Clean out any zero-qty levels.
                foreach (double price in m_PriceToDelete)
                {
                    m_StopPriceQty.Remove(price);
                    m_StopPriceList.Remove(price);
                }

                // Check whether there is still qty.  If so, we've flipped sides.
                if (qtyToRemove != 0)
                {
                    if (IsLogWrite)
                    {
                        Log.NewEntry(LogLevel.Major, "StopRule.UpdateStopLevels: {2} has fill qty {0} @ {1} remaining, flipped our position.",
                                     qtyToRemove.ToString(), fillPrice.ToString(), m_Name);
                    }
                    UpdateNewFill(-qtyToRemove, fillPrice, 0);   // Create new stop on other side of market.
                }
            }//if block
            //
            // Log
            if (IsLogWrite && Log.BeginEntry(LogLevel.Major))
            {
                Log.AppendEntry("StopRule.UpdateStopLevels: {1} {0} ", m_Name, m_Parent.Name);
                Log.AppendEntry("prev pos = {1}, new fills={2} @ {0} "
                                , fillPrice.ToString(), preFillPosition.ToString(), signedQty.ToString());
                Log.AppendEntry("StopInit={0} StopMulti={1} Stops: ", m_StopBase.ToString(), m_StopBaseMultiplier.ToString());
                if (m_StopPriceList.Count > 0)
                {
                    for (int i = 0; i < m_StopPriceList.Count; ++i)
                    {
                        double p = m_StopPriceList[i];
                        Log.AppendEntry("[{1} @ {0}] ", p.ToString(), m_StopPriceQty[p].ToString());
                    }
                }
                else
                {
                    Log.AppendEntry("[]. ");
                }
                Log.EndEntry();
            }
            // Tally the total position. Dumb by safe way (when called re-iteratively)!
            int n = 0;

            foreach (KeyValuePair <double, int> pqPair in m_StopPriceQty)
            {
                n += pqPair.Value;
            }
            m_LastPosition = n;
            //m_LastPosition += signedQty;
            if (m_StopPriceList.Count == 0 && m_LastPosition != 0)
            {
                return;
            }
        }//UpdateNewFill()
        // *****************************************************************
        // ****                     Constructors                        ****
        // *****************************************************************
        public ReconcilerForm(string[] cmdLineArgs)
        {
            InitializeComponent();
            AppInfo m_AppInfo = AppInfo.GetInstance("Breconcile", true);

            m_AppInfo.RequestShutdownAddHandler(new EventHandler(RequestShutDown));     // register my handler as the shutdown request handler.


            string filePath = string.Empty;

            if (cmdLineArgs != null && cmdLineArgs.Length > 0)
            {
                filePath = string.Format("{0}{1}", m_AppInfo.UserConfigPath, cmdLineArgs[0].Trim());
            }
            else
            {
                filePath = string.Format("{0}ReconcilerConfig.txt", m_AppInfo.UserConfigPath);
            }

            // here is temp hard code config file address
            // filePath = "\\\\fileserver\\Users\\DV_Ambre\\AmbreUsers\\dvbre\\Config\\ReconcilerConfig.txt";

            // Create the services defined in the config file.
            using (StringifiableReader reader = new StringifiableReader(filePath))
            {
                List <IStringifiable> objectList = reader.ReadToEnd();
                foreach (IStringifiable obj in objectList)
                {
                    if (obj is ReconcilerTaskHub)
                    {
                        ReconcilerTaskHub newHub = (ReconcilerTaskHub)obj;
                        m_ReconcilerTaskHubs.Add(newHub);
                        if (Log == null)
                        {
                            Log = newHub.Log;              // accept first Log as the form's log.
                        }
                        newHub.TaskCompleted += new EventHandler(Reconciler_RequestCompleted);
                        newHub.Stopping      += new EventHandler(Reconciler_Stopping);
                    }
                }
            }

            // Log start up.
            if (Log != null)
            {
                Log.NewEntry(LogLevel.Minor, "ReconcilerForm: Running config file {0}", filePath);
                if (Log.BeginEntry(LogLevel.Minor, "ReconcilerForm: {0} TaskHubs: ", m_ReconcilerTaskHubs.Count))
                {
                    foreach (ReconcilerTaskHub hub in m_ReconcilerTaskHubs)
                    {
                        Log.AppendEntry("<{0}>", hub.GetAttributes());
                    }
                }
            }

            // Start hubs
            foreach (ReconcilerTaskHub hub in m_ReconcilerTaskHubs)
            {
                hub.Start();
            }
        }