Example #1
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();
            }
        }
Example #2
0
        public static bool IsCriticalTradingTime(GatewayId p_gatewayId, DateTime p_timeUtc)
        {
            DateTime timeEt = Utils.ConvertTimeFromUtcToEt(p_timeUtc);

            if (timeEt.DayOfWeek == DayOfWeek.Saturday || timeEt.DayOfWeek == DayOfWeek.Sunday)   // quick check: if it is the weekend => not critical time.
            {
                return(false);
            }

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

            if (isMarketHoursValid && !isMarketTradingDay)
            {
                return(false);
            }

            foreach (var critTradingRange in GatewayExtensions.CriticalTradingPeriods)
            {
                if (critTradingRange.GatewayId != p_gatewayId)
                {
                    continue;
                }

                if (!isMarketHoursValid)
                {
                    return(true);                                // Caution: if DetermineUsaMarketTradingHours() failed, better to report that we are in a critical period.
                }
                DateTime critPeriodStartUtc = DateTime.MinValue; // Caution:
                if (critTradingRange.RelativeTimePeriod.Start.Base == RelativeTimeBase.BaseOnUsaMarketOpen)
                {
                    critPeriodStartUtc = marketOpenTimeUtc + critTradingRange.RelativeTimePeriod.Start.TimeOffset;
                }
                else if (critTradingRange.RelativeTimePeriod.Start.Base == RelativeTimeBase.BaseOnUsaMarketClose)
                {
                    critPeriodStartUtc = marketCloseTimeUtc + critTradingRange.RelativeTimePeriod.Start.TimeOffset;
                }

                DateTime critPeriodEndUtc = DateTime.MaxValue;
                if (critTradingRange.RelativeTimePeriod.End.Base == RelativeTimeBase.BaseOnUsaMarketOpen)
                {
                    critPeriodEndUtc = marketOpenTimeUtc + critTradingRange.RelativeTimePeriod.End.TimeOffset;
                }
                else if (critTradingRange.RelativeTimePeriod.End.Base == RelativeTimeBase.BaseOnUsaMarketClose)
                {
                    critPeriodEndUtc = marketCloseTimeUtc + critTradingRange.RelativeTimePeriod.End.TimeOffset;
                }

                if (critPeriodStartUtc <= p_timeUtc && p_timeUtc <= critPeriodEndUtc)   // if p_timeUtc is between [Start, End]
                {
                    return(true);
                }
            }

            return(false);
        }
Example #3
0
        public static bool IsInRegularUsaTradingHoursNow(TimeSpan p_maxAllowedStaleness)
        {
            DateTime utcNow = DateTime.UtcNow;

            // 1. quick response for trivial case that works most of the time, that don't need DetermineUsaMarketTradingHours()
            DateTime utcNowET = Utils.ConvertTimeFromUtcToEt(utcNow).Date;

            if (utcNowET.DayOfWeek == DayOfWeek.Saturday || utcNowET.DayOfWeek == DayOfWeek.Sunday)
            {
                return(false);
            }
            DateTime openInET = new DateTime(utcNowET.Year, utcNowET.Month, utcNowET.Day, 9, 30, 0);

            if (utcNowET < openInET)
            {
                return(false);
            }
            DateTime maxPossibleCloseInET = new DateTime(utcNowET.Year, utcNowET.Month, utcNowET.Day, 16, 0, 0); // usually it is 16:00, but when half-day trading, then it is 13:00

            if (utcNowET > openInET)
            {
                return(false);
            }

            // 2. During RTH on weekdays, we have to be more thorough.
            bool     isMarketTradingDay;
            DateTime openTimeUtc, closeTimeUtc;
            bool     isTradingHoursOK = Utils.DetermineUsaMarketTradingHours(utcNow, out isMarketTradingDay, out openTimeUtc, out closeTimeUtc, p_maxAllowedStaleness);

            if (!isTradingHoursOK)
            {
                Utils.Logger.Error("DetermineUsaMarketTradingHours() was not OK.");
                return(false);
            }
            else
            {
                if (!isMarketTradingDay)
                {
                    return(false);
                }
                if (utcNow < openTimeUtc)
                {
                    return(false);
                }
                if (utcNow > closeTimeUtc)
                {
                    return(false);
                }

                return(true);
            }
        }
Example #4
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();
            }
        }