Search Framework:
DateTime
Namespace: WealthLab.Core
Parent:

Covers a list of DateTime extension methods that assist with typical trading functions related to date and time. Call these methods like any other DateTime method using the method syntax. The first parameter, always this DateTime, specifies the type that the method operates on. See the examples for usage details.

Extension Methods
CalendarDaysBetweenDates
public static int CalendarDaysBetweenDates(this DateTime fromDate, DateTime toDate)
public static int CalendarDaysBetweenDates(this int fromDate, int toDate)
public static int CalendarDaysBetweenDates(this string fromDate, string toDate)

Returns the number of calendar days between fromDate and toDate. The result is positive if toDate is in the future, otherwise zero (same Date) or negative.

Remarks

  • If the string date overload is used, the date string must use the "yyyyMMdd" format, e.g. "20210416"
  • If the int date overload is used, the date int must use the yyyyMMdd format, e.g, 20210416
Example Code
using WealthLab.Backtest;
using System;
using WealthLab.Core;
using WealthLab.Indicators;
using System.Drawing;
using System.Collections.Generic;

namespace WealthScript123
{
	public class MyStrategy : UserStrategyBase
	{

		public override void Initialize(BarHistory bars)
		{
		}

		public override void Execute(BarHistory bars, int idx)
		{

			DateTime exp = bars.DateTimes[idx].NextOptionExpiryDate(bars);
			int calendarDaysToExpiry = bars.DateTimes[idx].CalendarDaysBetweenDates(exp);

			//annotate the bars with number of calendar days to Expiry
			DrawBarAnnotation(calendarDaysToExpiry.ToString(), idx, true, WLColor.Black, 9, true);

		}

	}
}

GetNextTradingDate
public static DateTime GetNextTradingDate(this DateTime dt1, BarHistory bars)
public static DateTime GetNextTradingDate(this DateTime dt, MarketDetails mkt)

Returns the DateTime the next trading day after dt for the bars or mkt. If the date passed to the method contains a time, it is preserved in the result. This method is useful to determine if the next day is the end of the week/month for signaling.

Example Code
using WealthLab.Backtest;
using System;
using WealthLab.Core;
using WealthLab.Indicators;

namespace WealthScript123
{
	public class MyStrategy : UserStrategyBase
	{
		//create indicators and other objects here, this is executed prior to the main trading loop
		public override void Initialize(BarHistory bars)
		{
		}

		//execute the strategy rules here, this is executed once for each bar in the backtest history
		public override void Execute(BarHistory bars, int idx)
		{
			if (!HasOpenPosition(bars, PositionType.Long))
			{
				//if the next day is the end of the month, buy on the close
				if (bars.DateTimes[idx].GetNextTradingDate(bars).IsLastTradingDayOfMonth(bars))
					PlaceTrade(bars, TransactionType.Buy, OrderType.MarketClose, 0, "End of Month");
				
			}
			else
			{
				//exit the Position at the Close on the last day of the first week
				if (bars.DateTimes[idx].GetNextTradingDate(bars).IsLastTradingDayOfWeek(bars))
					PlaceTrade(bars, TransactionType.Sell, OrderType.MarketClose, 0, "End of Week");
			}
		}

	}
}

GetTime
public static int GetTime(this DateTime dt)

Returns the 24-hour 'HHmm' integer of the time part of dt. Seconds are ignored. This method is useful to create time-of-day trading filters without resorting to the use of TimeSpan.

Examples

  • 9:35 am => 935
  • 12:00 pm => 1200
  • 3:50 pm => 1550
Example Code
using WealthLab.Backtest;
using System;
using WealthLab.Core;
using WealthLab.Indicators;

namespace WealthScript123
{
    public class MyStrategy : UserStrategyBase
    {
        //create indicators and other objects here, this is executed prior to the main trading loop
        public override void Initialize(BarHistory bars)
        {
			_sma = SMA.Series(bars.Close, 20);
			PlotIndicator(_sma);
        }

        //execute the strategy rules here, this is executed once for each bar in the backtest history
        public override void Execute(BarHistory bars, int idx)
        {
            if (!HasOpenPosition(bars, PositionType.Long))
            {
				// don't enter before 10:15 am
				if (bars.DateTimes[idx].GetTime() < 1015)
					return; 
	            // after 10:15, buy if the close is above the moving avg
				if (bars.Close[idx] > _sma[idx])
					PlaceTrade(bars, TransactionType.Buy, OrderType.Market);
            }
			else
			{
				// sell on 2 consecutive closes below the moving avg
				if (bars.Close[idx] < _sma[idx] && bars.Close[idx - 1] < _sma[idx - 1])
					ClosePosition(LastPosition, OrderType.Market);
            }
        }

		SMA _sma; 
    }
}

IsHoliday
public static bool IsHoliday(this DateTime dt, BarHistory bars)

Returns true if the DateTime dt is a holiday for the specifed BarHistory bars, otherwise false.

Example Code
using WealthLab.Backtest;
using System;
using WealthLab.Core;
using WealthLab.Indicators;
using System.Drawing;
using System.Collections.Generic;

namespace WealthScript123
{
	public class MyStrategy : UserStrategyBase
	{
		TimeSeries _dayBeforeHoliday;

		public override	void Initialize(BarHistory bars)
		{
			//create a series that marks the day before a holiday with a 1
			_dayBeforeHoliday = new TimeSeries(bars.DateTimes, 0);

			DateTime nextDate;
			for (int bar = 0; bar < bars.Count; bar++)
			{
				//check if the next non-weekend day (in the future) is a holiday
				nextDate = bars.DateTimes[bar].Date;
				do
				{
					nextDate = nextDate.AddDays(1);
					int day = (int)nextDate.DayOfWeek;
					if (day == 0 || day == 6)  //skip Sunday or Saturday
						continue;

					if (nextDate.IsHoliday(bars))
						_dayBeforeHoliday[bar] = 1;

					break;
				} while (true);

				if (_dayBeforeHoliday[bar] == 1)
					SetBackgroundColorAllPanes(bars, bar, WLColor.FromArgb(40, WLColor.Green));
			}

		}

		public override	void Execute(BarHistory bars, int idx)
		{

		}
	}
}

IsLastTradingDayOfMonth
public static bool IsLastTradingDayOfMonth(this DateTime dt, BarHistory bars)

Returns true if the Date is the last trading day of a calendar month for the specifed BarHistory, otherwise false.

Example Code
using WealthLab.Backtest;
using System;
using WealthLab.Core;
using WealthLab.Indicators;
using System.Drawing;
using System.Collections.Generic;

namespace WealthScript123
{
	public class MyStrategy : UserStrategyBase
	{
		//create indicators and other objects here, this is executed prior to the main trading loop
		public override void Initialize(BarHistory bars)
		{
		}

		//execute the strategy rules here, this is executed once for each bar in the backtest history
		public override void Execute(BarHistory bars, int idx)
		{
			if (!HasOpenPosition(bars, PositionType.Long))
			{
				if (bars.DateTimes[idx].IsLastTradingDayOfMonth(bars))
					PlaceTrade(bars, TransactionType.Buy, OrderType.Market);
			}
			else
			{
				Position p = LastPosition;
				//sell after 5 bars
				if (idx + 1 - p.EntryBar >= 5)
					ClosePosition(p, OrderType.Market, 0, "Time-based");
			}
		}

		//declare private variables below

	}
}

IsLastTradingDayOfWeek
public static bool IsLastTradingDayOfWeek(this DateTime dt, BarHistory bars)

Returns true if the Date is the last trading day of a calendar week for the specifed BarHistory, otherwise false.

Example Code
using WealthLab.Backtest;
using System;
using WealthLab.Core;
using WealthLab.Indicators;
using System.Drawing;
using System.Collections.Generic;

namespace WealthScript123
{
	public class MyStrategy : UserStrategyBase
	{
		//create indicators and other objects here, this is executed prior to the main trading loop
		public override void Initialize(BarHistory bars)
		{
			PlotStopsAndLimits(3);
			_ib = Highest.Series(bars.Close, 20);
		}

		//execute the strategy rules here, this is executed once for each bar in the backtest history
		public override void Execute(BarHistory bars, int idx)
		{
			if (!HasOpenPosition(bars, PositionType.Long))
			{
				PlaceTrade(bars, TransactionType.Buy, OrderType.Stop, _ib[idx]);
			}
			else
			{
				Position p = LastPosition;
				
				//exit the Position at the Close on the last day of the week
				if (bars.DateTimes[idx].GetNextTradingDate(bars).IsLastTradingDayOfWeek(bars))
					PlaceTrade(bars, TransactionType.Sell, OrderType.MarketClose, 0, "End of Week");
			}
		}

		//declare private variables below
		IndicatorBase _ib; 

	}
}

IsOptionExpiry
public static bool IsOptionExpiry(this DateTime date)
public static bool IsOptionExpiry(this DateTime date, BarHistory bars)

The first version without the BarHistory parameter returns true if the date corresponds to the third Friday of a month, which is generally the monthly option expiration day. Otherwise the function returns false. The BarHistory overload allows the function to detect if the third Friday is a market holiday in which case the function will return true on the Thursday before the Friday holiday. Example: The U.S. Market celebrated Good Friday on 4/14/2022, consequently monthly options expired on 4/13/2022.

Example Code
using WealthLab.Backtest;
using System;
using WealthLab.Core;
using WealthLab.Indicators;
using System.Drawing;
using System.Collections.Generic;

namespace WealthScript123
{
	public class MyStrategy : UserStrategyBase
	{
		public override void Initialize(BarHistory bars)
		{

		}

		public override void Execute(BarHistory bars, int idx)
		{
			//make the background light blue on option expiry day
			if (bars.DateTimes[idx].IsOptionExpiry())
				SetBackgroundColorAllPanes(bars, idx, WLColor.FromArgb(40, WLColor.Blue));
		}
	}
}

IsTradingDay
public static bool IsTradingDay(this DateTime dt, BarHistory bars)

Returns true if the market trades on the day represented by DateTime dt. Time is ignored.

Example Code
using WealthLab.Backtest;
using System;
using WealthLab.Core;
using WealthLab.Indicators;
using System.Drawing;
using System.Collections.Generic;

namespace WealthScript123
{
	public class MyStrategy : UserStrategyBase
	{
		//create indicators and other objects here, this is executed prior to the main trading loop
		public override void Initialize(BarHistory bars)
		{
			//will the market trade on Dec 25, 2045?
			DateTime dte = new DateTime(2022, 12, 25);
			WriteToDebugLog("The market will trade on Dec 25, 2045: " + dte.IsTradingDay(bars));
		}

		//execute the strategy rules here, this is executed once for each bar in the backtest history
		public override void Execute(BarHistory bars, int idx)
		{

		}
	}
}

IsWeekend
public static bool IsWeekend(this DateTime dt)

Returns true if the DateTime dt falls on a Saturday or Sunday. This is a helper function that's used when calculating the next trading day, for example, but adding days to a date and checking if the result falls on a weekend or a holiday.


NextOptionExpiryDate
public static DateTime NextOptionExpiryDate(this DateTime date, BarHistory bars)

Returns DateTime of the next closest monthly options expiration date as of the specified date. Options expiration dates typically fall on the third Friday of every month.

Remarks

  • Returns the current date if it is an expiry date
  • If expiry Friday is a holiday, returns Thursday's date prior to the holday.
Example Code
using WealthLab.Backtest;
using System;
using WealthLab.Core;
using WealthLab.Indicators;
using System.Drawing;
using System.Collections.Generic;

namespace WealthScript123
{
	public class MyStrategy : UserStrategyBase
	{

		public override	void Initialize(BarHistory bars)
		{
		}


		public override	void Execute(BarHistory bars, int idx)
		{
			//make the background light	blue on	option expiry day
			if (bars.DateTimes[idx].IsOptionExpiry())
				SetBackgroundColor(bars, idx, WLColor.FromArgb(40, WLColor.Blue));

			if (!HasOpenPosition(bars, PositionType.Long))
			{
				//buy 4	trading	day	before the next	option expiry
				//using BarHistory method
				int daysToExpiry = bars.TradingDaysBetweenDates(bars.DateTimes[idx], bars.NextOptionExpiryDate(idx));

				//since	we buy on next bar,	test for 5 days
				if (daysToExpiry == 5)					
					PlaceTrade(bars, TransactionType.Buy, OrderType.Market);
			}
			else
			{
				//get the expiry after the position	entry bar
				DateTime expiryAfterEntry = bars.NextOptionExpiryDate(LastPosition.EntryBar);

				//now get the following	expiry date using the DateTime extension method
				DateTime nextExpiry	= expiryAfterEntry.AddDays(1).NextOptionExpiryDate(bars);

				int	daysToExpiry = bars.TradingDaysBetweenDates(bars.DateTimes[idx], nextExpiry);

				//sell 11 trading days before the next expiry
				if (daysToExpiry == 12)					
					PlaceTrade(bars, TransactionType.Sell, OrderType.Market);
			}
		}
	}
}

PreviousTradingDay
public static DateTime PreviousTradingDay(this DateTime dt, MarketDetails md)

Returns the DateTime of the trading day prior to the DateTime dt for the MarketDetails md. If dt has a time component, this is retained in the returned result.

Example Code
using WealthLab.Backtest;
using System;
using WealthLab.Core;
using WealthLab.Indicators;
using System.Drawing;
using System.Collections.Generic;

namespace WealthScript123
{
	public class MyStrategy : UserStrategyBase
	{
		public override void Initialize(BarHistory bars)
		{
			//find the previous trading date 1 year from the last bar
			DateTime dt	= bars.DateTimes[bars.Count - 1].AddYears(1);

			DateTime prevTradingDay = dt.PreviousTradingDay(bars.Market);
			WriteToDebugLog("The current date is " + dt.ToString("yyyy-MM-dd HH:mm"));
			WriteToDebugLog("The trading day prior date 1 year from now is " + prevTradingDay.ToString("yyyy-MM-dd HH:mm"));
		}

		public override void Execute(BarHistory bars, int idx)
		{

		}
	}
}

WeekOfYear
public static int WeekOfYear(this DateTime dte)

Returns a number for the week of the year, 1 to 52 or 53.

Remarks

  • Week #1 is the first full week in January, days from Sunday to Saturday.
  • Unless Jan 1st is on Sunday, the first days in Jan will often be the last days in the last week of the previous year.
Example Code
using WealthLab.Backtest;
using System;
using WealthLab.Core;
using WealthLab.Data;
using WealthLab.Indicators;

namespace WealthScript123
{
    public class MyStrategy : UserStrategyBase
    {
        public override void Initialize(BarHistory bars)
        {
			StartIndex = 1;	        
        }

        public override void Execute(BarHistory bars, int idx)
        {
			//identify the first day of the week by its WeekOfYear number
			int woy = bars.DateTimes[idx].WeekOfYear();
			if (woy != bars.DateTimes[idx - 1].WeekOfYear())
				DrawBarAnnotation(woy.ToString(), idx, true, WLColor.NeonGreen, 14);

		}
	}
}