Beispiel #1
0
        internal void CurrentStateToHealthMonitorWebsite(TcpClient p_tcpClient, HealthMonitorMessage p_message)
        {
            var hmDataIn = Utils.LoadFromJSON<HMtoDashboardData>(p_message.ParamStr);
            HMtoDashboardData hmDataOut = null;
            if (String.Equals(hmDataIn.CommandToBackEnd, "OnlyGetData", StringComparison.CurrentCultureIgnoreCase))
            {
                hmDataOut = new HMtoDashboardData() { ResponseToFrontEnd = "OK" };
                ReportCurrentStateToWebsiteInJSON(hmDataOut);
            }
            else if (String.Equals(hmDataIn.CommandToBackEnd, "ApplyTheDifferences", StringComparison.CurrentCultureIgnoreCase))
            {
                // 1. apply new settings 
                ApplyTheDifferencesComingFromWebsite(hmDataIn);
                // 2. read out the current state 
                hmDataOut = new HMtoDashboardData() { ResponseToFrontEnd = "OK" };
                ReportCurrentStateToWebsiteInJSON(hmDataOut);
            }
            else
            {
                hmDataOut = new HMtoDashboardData() { ResponseToFrontEnd = "Error: unrecognised CommandToBackEnd" };
            }

            if (p_message.ResponseFormat == HealthMonitorMessageResponseFormat.JSON)
            {
                var jsonStr = Utils.SaveToJSON<HMtoDashboardData>(hmDataOut);
                BinaryWriter bw = new BinaryWriter(p_tcpClient.GetStream());
                bw.Write(jsonStr);
                //bw.Write(@"{""AppOk"":""OK"",""StartDate"":""1998-11-16T00:00:00"",""StartDateLoc"":""1998-11-16T00:00:00.000Z"",""StartDateTimeSpanStr"":"""",""DailyEmailReportEnabled"":false,""RtpsOk"":""OK"",""RtpsTimerEnabled"":false,""RtpsTimerFrequencyMinutes"":-999,""RtpsDownloads"":[""aaaaaaaaaaaaaaaaaaaaaaaaaa"",""b""],""VBrokerOk"":""OK"",""ProcessingVBrokerMessagesEnabled"":false,""VBrokerReports"":[""a"",""b""],""VBrokerDetailedReports"":[""a"",""b""],""CommandToBackEnd"":""OnlyGetData"",""ResponseToFrontEnd"":""OK""}");
            }
        }
Beispiel #2
0
        public virtual void Timer_Elapsed(object?state)     // Timer is coming on a ThreadPool thread
        {
            Utils.Logger.Info("Trigger.Timer_Elapsed() ");
            NextScheduleTimeUtc = null;

            bool     isMarketTradingDay;
            DateTime marketOpenTimeUtc, marketCloseTimeUtc;
            bool     isMarketHoursValid = Utils.DetermineUsaMarketTradingHours(DateTime.UtcNow, out isMarketTradingDay, out marketOpenTimeUtc, out marketCloseTimeUtc, TimeSpan.FromDays(3));

            if (!isMarketHoursValid)
            {
                Utils.Logger.Error("DetermineUsaMarketTradingHours() was not ok.");
            }

            SqTaskScheduler.gTaskScheduler.ScheduleTrigger(this, isMarketHoursValid, isMarketTradingDay, marketOpenTimeUtc, marketCloseTimeUtc);

            try
            {
                if (SqTask != null)
                {
                    SqExecution sqExecution = ((SqTask)SqTask).ExecutionFactory();
                    sqExecution.SqTask  = (SqTask)SqTask;
                    sqExecution.Trigger = this;
                    sqExecution.Run();
                }
            }
            catch (Exception e)
            {
                Utils.Logger.Error(e, "Trigger.Timer_Elapsed() Exception");
                HealthMonitorMessage.SendAsync($"Exception in BrokerTaskExecutionThreadRun(). Exception: '{ e.ToStringWithShortenedStackTrace(1600)}'", HealthMonitorMessageID.SqCoreWebCsError).TurnAsyncToSyncTask();
            }
        }
Beispiel #3
0
        List<Tuple<DateTime, bool, string, string>> m_VbReport = new List<Tuple<DateTime, bool, string, string>>(); // List<> is not thread safe: <Date, IsOk, BriefReport, DetailedReport>

        // this is called every time the VirtualBroker send OK or Error: after every simulated trading
        // 1. General Error message looks like this. No HTML. Not Strategy (UberVXX, HarryLong) specific. VBroker can crash anywhere, without any strategy affiliation.
        // Message ID:"ReportErrorFromVirtualBroker", ParamStr: "Exception in BrokerTaskExecutionThreadRun Exception: . Exception: 'System.Exception: StrongAssert failed (severity==ThrowException): There is no point continuing if portfolioUSdSize cannot be calculated. After that we cannot calculate new stock Volumes from weights.
        //at SqCommon.StrongAssert.Fail_core(Severity p_severity, String p_message, Object[] p_args) in /home/ubuntu/SQ/Server/VirtualBroker/src/SQLab.Common/Utils/StrongAssert.cs:line 127
        // at VirtualBroke...'", ResponseFormat: "None"
        // 2. Strategy messages OK. Strategy specific. HTML format.
        // Message ID:"ReportOkFromVirtualBroker", ParamStr: "<BriefReport>BrokerTask HarryLong was OK.</BriefReport><DetailedReport>11-09T20:59:49: 'HarryLong'<br/><font color="#10ff10">Target: UVXY:-35%, TMV:-65%</font><br/>Real SellAsset  6 UVXY ($82)<br/>Real BuyAsset  29 TMV ($626)<br/>Real BuyAsset  46 UVXY ($626)<br/>Real BuyAsset  581 TMV ($12541)<br/></DetailedReport>", ResponseFormat: "None"
        private void MessageFromVirtualBroker(TcpClient p_tcpClient, HealthMonitorMessage p_message)
        {
            if (p_message.ResponseFormat == HealthMonitorMessageResponseFormat.String)
            {
                BinaryWriter bw = new BinaryWriter(p_tcpClient.GetStream());
                bw.Write("FromServer: Message received, saved and starting processing: " + p_message.ParamStr);
            }

            if (!m_persistedState.IsProcessingVBrokerMessagesEnabled)
                return;

            //string healthMonitorMsg = $"<BriefReport>{briefReport}</BriefReport><DetailedReport>{detailedReportSb.ToString()}</DetailedReport>";
            // or in a case of VBroker crash, it is simply a HealthMonitorMessageID.ReportErrorFromVirtualBroker ID, with no "<BriefReport>" structure.
            string briefReport = null, detailedReport = null;
            int briefReportBegin = p_message.ParamStr.IndexOf("<BriefReport>");
            if (briefReportBegin != -1)
            {
                int briefReportEnd = p_message.ParamStr.IndexOf("</BriefReport>", briefReportBegin + "<BriefReport>".Length);
                if (briefReportEnd != -1)
                {
                    int detailedReportBegin = p_message.ParamStr.IndexOf("<DetailedReport>", briefReportEnd + "</BriefReport>".Length);
                    if (detailedReportBegin != -1)
                    {
                        int detailedReportEnd = p_message.ParamStr.IndexOf("</DetailedReport>", briefReportBegin + "<DetailedReport>".Length);
                        if (detailedReportEnd != -1)
                        {
                            briefReport = p_message.ParamStr.Substring(briefReportBegin + "<BriefReport>".Length, briefReportEnd - briefReportBegin - "<BriefReport>".Length);
                            detailedReport = p_message.ParamStr.Substring(detailedReportBegin + "<DetailedReport>".Length, detailedReportEnd - detailedReportBegin - "<DetailedReport>".Length);
                        }
                    }
                }
            }

            bool isError = (p_message.ID == HealthMonitorMessageID.ReportErrorFromVirtualBroker);
            if (!isError && (briefReport != null))
            {
                // sometimes the message seems OK, but if the messageParam contains the word "Error" treat it as error. For example, if this email was sent to the user, with the Message that everything is OK, treat it as error
                // "***Trade: ERROR"   + "*** StrongAssert failed (severity==Exception): BrokerAPI.GetStockMidPoint(VXX,...) failed"
                // "ibNet_ErrorMsg(). TickerID: 742, ErrorCode: 404, ErrorMessage: 'Order held while securities are located.'
                // "Error. A transaction was not executed. p_brokerAPI.GetExecutionData = null for Sell VXX Volume: 266. Check that it was not executed and if not, perform it manually then enter into the DB.
                isError = (briefReport.IndexOf("Error", StringComparison.CurrentCultureIgnoreCase) != -1);  // in DotNetCore, there is no StringComparison.InvariantCultureIgnoreCase
            }

            lock (m_VbReport)
                m_VbReport.Add(new Tuple<DateTime, bool, string, string>(DateTime.UtcNow, !isError, ((briefReport != null) ? briefReport : "ReportFromVirtualBroker without BriefReport"), ((detailedReport != null) ? detailedReport : p_message.ParamStr)));

            if (isError)
            {
                Utils.Logger.Info("ErrorFromVirtualBroker().");
                InformSupervisors("SQ HealthMonitor: ERROR from VirtualBroker.", $"SQ HealthMonitor: ERROR from VirtualBroker. MessageParamStr: { ((briefReport != null) ? briefReport : p_message.ParamStr) }", 
                    "There is an Error in Virtual Broker. ... I repeat: Error in Virtual Broker.", ref m_lastVbInformSupervisorLock, ref m_lastVbErrorEmailTime, ref m_lastVbErrorPhoneCallTime);
            }
        }
Beispiel #4
0
        DateTime m_lastSqWebsiteErrorPhoneCallTime = DateTime.MinValue;    // don't call if it was made in the last 30 minutes
      
        private void ErrorFromSqLabWebsite(TcpClient p_tcpClient, HealthMonitorMessage p_message)
        {
            if (!m_persistedState.IsProcessingSQLabWebsiteMessagesEnabled)
                return;

            if (p_message.ResponseFormat == HealthMonitorMessageResponseFormat.String)
            {
                BinaryWriter bw = new BinaryWriter(p_tcpClient.GetStream());
                bw.Write("FromServer: Message received, saved and starting processing: " + p_message.ParamStr);
            }

            Utils.Logger.Info("ErrorFromSqLabWebsite().");
            InformSupervisors("SQ HealthMonitor: ERROR from SQLab Website.", $"SQ HealthMonitor: ERROR from SQLab Website. MessageParamStr: { p_message.ParamStr}", null, ref m_lastSqWebsiteInformSupervisorLock, ref m_lastSqWebsiteErrorEmailTime, ref m_lastSqWebsiteErrorPhoneCallTime);
        }
Beispiel #5
0
        private void SchedulerThreadRun()
        {
            try
            {
                Thread.CurrentThread.Name = "VBroker scheduler";
                Thread.Sleep(TimeSpan.FromSeconds(5));  // wait 5 seconds, so that IBGateways can connect first
                m_schedulerStartupTime = DateTime.UtcNow;

                // maybe loop is not required.
                // in the past we try to get UsaMarketOpenOrCloseTime() every 30 minutes. It was determined from YFinance intrady. "sleep 30 min for DetermineUsaMarketOpenOrCloseTime()"
                // however, it may be a good idea that the Scheduler periodically wakes up and check Tasks
                while (true)
                {
                    Utils.Logger.Info($"SchedulerThreadRun() loop BEGIN. Awake at every {cVbSchedulerSleepMinutes}min.");
                    bool     isMarketTradingDay;
                    DateTime marketOpenTimeUtc, marketCloseTimeUtc;
                    //  Utils.DetermineUsaMarketTradingHours():  may throw an exception once per year, when Nasdaq page changes. BrokerScheduler.SchedulerThreadRun() catches it and HealthMonitor notified in VBroker.
                    bool isMarketHoursValid = Utils.DetermineUsaMarketTradingHours(DateTime.UtcNow, out isMarketTradingDay, out marketOpenTimeUtc, out marketCloseTimeUtc, TimeSpan.FromDays(3));
                    if (!isMarketHoursValid)
                    {
                        Utils.Logger.Error("DetermineUsaMarketTradingHours() was not ok.");  // but we should continue and schedule Daily tasks not related to MarketTradingHours
                    }
                    foreach (SqTask sqTask in gSqTasks)
                    {
                        foreach (SqTrigger trigger in sqTask.Triggers)
                        {
                            ScheduleTrigger(trigger, isMarketHoursValid, isMarketTradingDay, marketOpenTimeUtc, marketCloseTimeUtc);
                        }
                    }

                    Thread.Sleep(TimeSpan.FromMinutes(cVbSchedulerSleepMinutes));     // try reschedulement in 30 minutes
                }
            }
            catch (Exception e)
            {
                //  Utils.DetermineUsaMarketTradingHours():  may throw an exception once per year, when Nasdaq page changes. BrokerScheduler.SchedulerThreadRun() catches it and HealthMonitor notified in VBroker.
                HealthMonitorMessage.SendAsync($"Exception in Scheduler.RecreateTasksAndLoopThread. Exception: '{ e.ToStringWithShortenedStackTrace(1600)}'", HealthMonitorMessageID.SqCoreWebCsError).TurnAsyncToSyncTask();
            }
        }
Beispiel #6
0
        internal async void TestHealthMonitorListenerBySendingErrorFromVirtualBroker()
        {
            // see HealthMonitorMessage.SendMassage for simpler application that will not read the response
            TcpClient client = new TcpClient();
            Task task = client.ConnectAsync(ServerIp.HealthMonitorPublicIp, HealthMonitorMessage.DefaultHealthMonitorServerPort);
            if (await Task.WhenAny(task, Task.Delay(TimeSpan.FromSeconds(10))) != task)
            {
                Console.WriteLine("Error: client.Connect() timeout.");
                return;
            }

            HealthMonitorMessage message = new HealthMonitorMessage()
            {
                ID = HealthMonitorMessageID.ReportErrorFromVirtualBroker,
                ParamStr = "Error reason here",
                ResponseFormat = HealthMonitorMessageResponseFormat.String
            };

            BinaryWriter bw = new BinaryWriter(client.GetStream());
            message.SerializeTo(bw);
            //bw.Write("I am VirtualBroker");

            if (message.ResponseFormat != HealthMonitorMessageResponseFormat.None)
            {
                BinaryReader br = new BinaryReader(client.GetStream());
                Console.WriteLine(br.ReadString());
            }
            Utils.TcpClientDispose(client);
        }