}// 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()
}//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()
}//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()
// // #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()
}// 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()
// #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(); } }