// // #endregion//Constructors #region Public Methods // ***************************************************************** // **** Public Methods **** // ***************************************************************** /// <summary> /// When an instrument is clicked on in the position viewer window, that window /// calls this routine letting us know which instrument is active. /// </summary> /* * public void SetInstrument(FillHub fillHub, Misty.Lib.Products.InstrumentBase instrument) * { * m_CurrentInstrument = instrument; // set current instrument * m_FillHub = fillHub; // set current fill hub * this.Text = string.Format("Add Fills - {0}", m_CurrentInstrument.FullName); * this.labelInstrumentName.Text = m_CurrentInstrument.FullName; * this.labelExpirationDate.Text = string.Format("{0:ddd dd MMM yyyy}", m_CurrentInstrument.ExpirationDate); * * // Update Markets * Misty.Lib.BookHubs.Book aBook; * if (m_Market.TryEnterReadBook(out aBook)) * { * foreach (Misty.Lib.BookHubs.MarketInstrument mktInstr in aBook.Instruments.Values) * { * if (mktInstr.Name.Equals(m_CurrentInstrument.FullName)) * { * labelAskPrice.Text = mktInstr.Price[Misty.Lib.Utilities.QTMath.AskSide][0].ToString(); * labelBidPrice.Text = mktInstr.Price[Misty.Lib.Utilities.QTMath.BidSide][0].ToString(); * labelAskQty.Text = mktInstr.Qty[Misty.Lib.Utilities.QTMath.AskSide][0].ToString(); * labelBidQty.Text = mktInstr.Qty[Misty.Lib.Utilities.QTMath.BidSide][0].ToString(); * break; * } * } * m_Market.ExitReadBook(aBook); * } * // Reset defaults * SetConfirmMode(buttonSubmitFill,false,0); * }//SetInstrument() * // */ // // public void SetInstrument(FillHub fillHub, Misty.Lib.Products.InstrumentName instrument) { m_CurrentInstrument = instrument; // set current instrument m_FillHub = fillHub; // set current fill hub this.Text = string.Format("Add Fills - {0}", m_CurrentInstrument.FullName); this.labelInstrumentName.Text = m_CurrentInstrument.FullName; /* * Misty.Lib.Products.InstrumentBase instrBase; * if (m_Market.TryGetInstrument(instrument, out instrBase)) * { * this.labelExpirationDate.Text = string.Format("{0:ddd dd MMM yyyy}", instrBase.ExpirationDate); * } * else * this.labelExpirationDate.Text = "unknown market instr"; */ TradingTechnologies.TTAPI.InstrumentDetails details; if (m_Market.TryLookupInstrumentDetails(instrument, out details)) { this.labelExpirationDate.Text = string.Format("{0:ddd dd MMM yyyy}", details.ExpirationDate.ToDateTime()); } else { this.labelExpirationDate.Text = "unknown market instr"; } // Update Markets Misty.Lib.BookHubs.Book aBook; if (m_Market.TryEnterReadBook(out aBook)) { foreach (Misty.Lib.BookHubs.Market mktInstr in aBook.Instruments.Values) { if (mktInstr.Name.Equals(m_CurrentInstrument)) { labelAskPrice.Text = mktInstr.Price[Misty.Lib.Utilities.QTMath.AskSide][0].ToString(); labelBidPrice.Text = mktInstr.Price[Misty.Lib.Utilities.QTMath.BidSide][0].ToString(); labelAskQty.Text = mktInstr.Qty[Misty.Lib.Utilities.QTMath.AskSide][0].ToString(); labelBidQty.Text = mktInstr.Qty[Misty.Lib.Utilities.QTMath.BidSide][0].ToString(); break; } } m_Market.ExitReadBook(aBook); } // Reset defaults SetConfirmMode(buttonSubmitFill, false, 0); }//SetInstrument()
}// HubEventHandler() // // // ***************************************************** // **** ProcessRequest() **** // ***************************************************** /// <summary> /// Processes job requests from user. /// </summary> private void ProcessRequest(RequestEventArg eventArg) { bool triggerRequestCompletedEvent = false; // // Multiple Sequential Requests // if (eventArg.Type == RequestType.MultipleSequentialRequests) // this contains one or more child tasks to complete. { RequestEventArg currentWorkingRequest = null; // the child-request that we are currently working on. if (eventArg.TryGetNextUnsuccessfulChild(out currentWorkingRequest)) { eventArg.Status = RequestStatus.ContinueWorking; // set parent as "working" if (currentWorkingRequest.Status == RequestStatus.Success) // Usually, the "current" child is not finished successfully, { // but if its the last child, then it signals the end of the task. eventArg.Status = RequestStatus.Success; // Mark parent for success... triggerRequestCompletedEvent = true; } else if (currentWorkingRequest.Status == RequestStatus.Failed) // the last non-successful child says its failed... { eventArg.Status = RequestStatus.Failed; // done. Failed request triggerRequestCompletedEvent = true; } else { Log.BeginEntry(LogLevel.Minor, "ProcessRequest: MultipleSequentialRequests {0}", eventArg); Log.AppendEntry(" ----> {0}", currentWorkingRequest); // output the current child to work. Log.EndEntry(); ProcessRequest(currentWorkingRequest); // continue trying to work this task. // TODO: fix this. If the currentWorkingREquest is complete, we might consider processing the // next request immediately, or not based on its allowed starting time. if (!m_WorkingRequests.Contains(eventArg)) // make sure that we will revist this parent event again... { Log.NewEntry(LogLevel.Minor, "ProcessRequest: MultipleSequentialRequests. Adding to waiting queue."); m_WorkingRequests.Add(eventArg); } else { Log.NewEntry(LogLevel.Minor, "ProcessRequest: MultipleSequentialRequests. Already in waiting queue."); } } } } // // Monitor Copy New Files // else if (eventArg.Type == RequestType.MonitorCopyNewFiles) { Log.BeginEntry(LogLevel.Minor, "ProcessRequest: {0}", eventArg); List <string> localFileNamesCopied; // names of files discovered on FTP site. if (m_FtpReader.TryCopyNewRemoteFilesToLocal(m_StatementPath, out localFileNamesCopied)) { // Success making FTP connection! if (localFileNamesCopied.Count > 0) // we consider a success that the files we waiting for are there now. { eventArg.Status = RequestStatus.Success; // update request state eventArg.Data = new List <object>(localFileNamesCopied); // update data RequestEventArg parentRequest; if (eventArg.TryGetParent(out parentRequest)) { this.HubEventEnqueue(parentRequest); // strobe the parent to attempt next task... } else { triggerRequestCompletedEvent = true; // otherwise, we are done, trigger event. } } else { // There were no new files yet. // Test that we dont already have a latest file... this would happen only if we ran // the code twice in one day... perform some check here. if (DateTime.Now.CompareTo(eventArg.GiveUpTime) > 0) { eventArg.Status = RequestStatus.Failed; RequestEventArg parentRequest; if (eventArg.TryGetParent(out parentRequest)) { this.HubEventEnqueue(parentRequest); // strobe the parent to attempt next task... } else { triggerRequestCompletedEvent = true; // otherwise, we are done, trigger event. } } else { eventArg.Status = RequestStatus.ContinueWorking; // We will try this again. if (!eventArg.IsChild && !m_WorkingRequests.Contains(eventArg)) { m_WorkingRequests.Add(eventArg); } } }// if there are new files } else { // Failed to event connect properly to FTP Log.AppendEntry(" FTP Connection failed."); if (DateTime.Now.CompareTo(eventArg.GiveUpTime) > 0) { eventArg.Status = RequestStatus.Failed; RequestEventArg parentRequest; if (eventArg.TryGetParent(out parentRequest)) { this.HubEventEnqueue(parentRequest); // strobe the parent to attempt next task... } else { triggerRequestCompletedEvent = true; // otherwise, we are done, trigger event. } } else { eventArg.Status = RequestStatus.ContinueWorking; // We will try this again. if (!eventArg.IsChild && !m_WorkingRequests.Contains(eventArg)) { m_WorkingRequests.Add(eventArg); } } } Log.EndEntry(); } // // Reconcile Statement // else if (eventArg.Type == RequestType.ReconcileStatement) { bool isSuccessful = true; // track our success in reconciling. // // Read statement // RCG.StatementReader statement; DateTime settlementDateTime; settlementDateTime = new DateTime(2013, 04, 8, 16, 15, 0); // DEBUG TryReadRCGStatement(settlementDateTime, out statement); // read RCG statements - date is settlement date. string statementFileName = statement.FilePathForPosition.Substring(statement.FilePathForPosition.LastIndexOf('_') + 1); // keep everything after "_" int n = statementFileName.LastIndexOf('.'); statementFileName = statementFileName.Substring(0, n); DateTime statementTimeStamp; if (!DateTime.TryParseExact(statementFileName, "yyyyMMdd", System.Globalization.DateTimeFormatInfo.CurrentInfo, System.Globalization.DateTimeStyles.None, out statementTimeStamp)) { // Failed to interpret date on file! isSuccessful = false; } // // Read drops // if (isSuccessful) { StringBuilder report = new StringBuilder(); // Full report StringBuilder currentItem = new StringBuilder(); foreach (string acctNumber in statement.m_PortfolioPosition.Keys) // for each account number found in the statement... { string baseFileName = string.Format("FillBooks_828{0}", acctNumber); BookReaders.EventPlayer eventPlayer = new BookReaders.EventPlayer(m_DropPath, baseFileName, settlementDateTime); if (eventPlayer.SeriesList.Count == 0) // No information about this account. { continue; // next account } report.AppendFormat("Acct# {0}\n", acctNumber); // RCG acct numbers from statement are missing first 3 chars. const string fmt = " {0,-32}{1,8}\t{2,-24}\n"; foreach (string rcgInstrDescr in statement.m_PortfolioPosition[acctNumber].Keys) // loop thru instrDescriptions - items in statement { currentItem.Clear(); // clear this line. Misty.Lib.Products.InstrumentName rcgInstrumentName; Misty.Lib.Products.Product mistyProduct; if (statement.m_InstrDescrToInstrName.TryGetValue(rcgInstrDescr, out rcgInstrumentName)) { int ourQty = 0; // qty computed from drop files if (statement.m_RcgToBreProduct.TryGetValue(rcgInstrumentName.Product, out mistyProduct)) { Misty.Lib.Products.InstrumentName mistyInstrumentName = new Misty.Lib.Products.InstrumentName(mistyProduct, rcgInstrumentName.SeriesName); BookReaders.EventSeries series; if (eventPlayer.SeriesList.TryGetValue(mistyInstrumentName, out series)) { Misty.Lib.OrderHubs.Fill fill; if (series.TryGetStateAt(settlementDateTime, out fill)) { ourQty = fill.Qty; currentItem.AppendFormat(fmt, mistyInstrumentName, ourQty, fill.LocalTime); } else { } } } else { // Unknown product mapping between RCG and TT! currentItem.AppendFormat(fmt, "unknown", "-", "-"); } // // Statement qty // int statementQty = 0; // qty from statement List <Misty.Lib.OrderHubs.Fill> fills = statement.m_PortfolioPosition[acctNumber][rcgInstrDescr]; foreach (Misty.Lib.OrderHubs.Fill aFill in fills) { statementQty += aFill.Qty; } currentItem.AppendFormat(fmt, rcgInstrDescr, statementQty, statementTimeStamp.ToShortDateString()); if (statementQty != ourQty) { currentItem.Remove(0, 1); currentItem.Insert(0, "*"); } }// try get rcgInstrumentName report.Append(currentItem); } //next rcgInstrDescr } //next acctNumber Log.NewEntry(LogLevel.Major, "ReconcileStatement: \r\n{0}", report.ToString()); // write report to Log file. } // // Exit // if (isSuccessful) { eventArg.Status = RequestStatus.Success; } else { eventArg.Status = RequestStatus.Failed; } RequestEventArg parentRequest; if (eventArg.TryGetParent(out parentRequest)) { this.HubEventEnqueue(parentRequest); // strobe the parent to attempt next task... } else { triggerRequestCompletedEvent = true; // otherwise, we are done, trigger event. } } // // Debug Test // else if (eventArg.Type == RequestType.DebugTest) { Log.BeginEntry(LogLevel.Minor, "ProcessRequest: {0}", eventArg); if (eventArg.Data == null) { Log.AppendEntry(" First failure."); eventArg.Data = new List <object>(); eventArg.Data.Add(1); // first failure eventArg.Status = RequestStatus.ContinueWorking; } else if (((int)eventArg.Data[0]) > 2) { // Success Log.AppendEntry(" Success!"); eventArg.Status = RequestStatus.Success; RequestEventArg parent; if (eventArg.TryGetParent(out parent)) { this.HubEventEnqueue(parent); } } else { // another failure int n = (int)eventArg.Data[0]; eventArg.Data[0] = n + 1; Log.AppendEntry(" {0} failures, try again.", n); eventArg.Status = RequestStatus.ContinueWorking; // We will try this again. if (!eventArg.IsChild && !m_WorkingRequests.Contains(eventArg)) { m_WorkingRequests.Add(eventArg); } } Log.EndEntry(); } else if (eventArg.Type == RequestType.Stop) { Shutdown(); base.Stop(); } else { Log.BeginEntry(LogLevel.Minor, "ProcessRequest: {0}", eventArg); Log.AppendEntry(" request type not implemented."); Log.EndEntry(); } // Exit if (triggerRequestCompletedEvent) { OnRequestCompleted(eventArg); } }//ProcessRequest()
} // ReadStatements() // // // // ***************************************************************** // **** Create InstrumentName() **** // ***************************************************************** private bool CreateInstrumentName(string typeCodeStr, string callPutFlag, string instrDescStr, string instrSymbolStr, out Misty.Lib.Products.Product rcgProduct, out Misty.Lib.Products.InstrumentName rcgInstrumentName) { int n; bool isOption = false; if (callPutFlag.Equals("C")) { isOption = true; } else if (callPutFlag.Equals("P")) { isOption = true; } if (isOption) { Misty.Lib.Products.ProductTypes mistyProductType = Misty.Lib.Products.ProductTypes.Option; string exchStr = string.Empty; string instrStr = instrDescStr; string seriesName = instrDescStr; rcgProduct = new Misty.Lib.Products.Product(exchStr, instrStr, mistyProductType); rcgInstrumentName = new Misty.Lib.Products.InstrumentName(rcgProduct, seriesName); } else if (string.IsNullOrEmpty(typeCodeStr) || typeCodeStr.Equals("F")) { // futures format = "DEC 13 TOCOM GOLD" Misty.Lib.Products.ProductTypes mistyProductType = Misty.Lib.Products.ProductTypes.Future; string[] elements; try { elements = instrDescStr.Split(DelimSpace, StringSplitOptions.RemoveEmptyEntries); int nextPtr = 0; // // Instrument date extraction // string seriesName; if (Int32.TryParse(elements[0], out n)) { // Seems to be "dd MMM yy" format, since first element is integer n = "dd" string s = elements[1].Trim(); // extract month part string monthName = string.Format("{0}{1}", s.Substring(0, 1).ToUpper(), s.Substring(1, 2).ToLower()); // MAY --> May seriesName = string.Format("{0:00}{1}{2}", n, monthName, elements[2].Trim()); // 08May13 for example seriesName = "CA 3M"; nextPtr = 3; // ptr to next element. } else { // Seems to be "MMM yy" format string s = elements[0].Trim(); // extract month part string monthName = string.Format("{0}{1}", s.Substring(0, 1).ToUpper(), s.Substring(1, 2).ToLower()); // MAY --> May seriesName = string.Format("{0}{1}", monthName, elements[1].Trim()); nextPtr = 2; // ptr to next element. } string exchStr; string instrStr; int remainingElements = elements.Length - nextPtr; if (remainingElements == 1) { // No obvious delineation between product and exch? // Assume a 3-character exchange code! I believe RCG uses fixed length fields... string s = elements[nextPtr].Trim(); exchStr = s.Substring(0, 3); // First 3 chars instrStr = s.Substring(3); // remaining symbol nextPtr++; } else { exchStr = elements[nextPtr].Trim(); // presume exch name is ONE-word long nextPtr++; instrStr = elements[nextPtr].Trim(); nextPtr++; while (nextPtr < elements.Length) { instrStr = string.Format("{0} {1}", instrStr, elements[nextPtr].Trim()); nextPtr++; } } rcgProduct = new Misty.Lib.Products.Product(exchStr, instrStr, mistyProductType); rcgInstrumentName = new Misty.Lib.Products.InstrumentName(rcgProduct, seriesName); } catch (Exception) { // TODO: Write error message to log, and continue. rcgProduct = new Misty.Lib.Products.Product(); rcgInstrumentName = new Misty.Lib.Products.InstrumentName(); return(false); } } else { rcgProduct = new Misty.Lib.Products.Product(); rcgInstrumentName = new Misty.Lib.Products.InstrumentName(); } // Exit return(true); }// CreateInstrumentName()