diff --git a/Common/Securities/Future/Futures.cs b/Common/Securities/Future/Futures.cs
index 9227eb4ff3da..2c228068d1a4 100644
--- a/Common/Securities/Future/Futures.cs
+++ b/Common/Securities/Future/Futures.cs
@@ -1388,6 +1388,12 @@ public static class Indices
/// The symbol
public const string VIX = "VX";
+ ///
+ /// VIX Mini Futures
+ ///
+ /// The symbol
+ public const string VIXMini = "VXM";
+
///
/// E-mini Russell 2000 Futures
///
diff --git a/Common/Securities/Future/FuturesExpiryFunctions.cs b/Common/Securities/Future/FuturesExpiryFunctions.cs
index c0cbc9fe9d74..30d93fc2e437 100644
--- a/Common/Securities/Future/FuturesExpiryFunctions.cs
+++ b/Common/Securities/Future/FuturesExpiryFunctions.cs
@@ -543,6 +543,31 @@ public static Func FuturesExpiryFunction(Symbol symbol)
return expiryDate.Add(new TimeSpan(13, 0, 0));
})
},
+ // VIX Mini Futures (VXM): https://cdn.cboe.com/resources/futures/VXM_Contract_Specifications.pdf
+ {Symbol.Create(Futures.Indices.VIXMini, SecurityType.Future, Market.CFE), (time =>
+ {
+ // Trading occurs 30 days before S&P 500 option expiration (third Friday of contract month).
+ // Last trading day is the Wednesday 30 days prior to the third Friday of the contract month.
+ var market = Market.CFE;
+ var symbol = Futures.Indices.VIXMini;
+ var nextThirdFriday = FuturesExpiryUtilityFunctions.ThirdFriday(time.AddMonths(1));
+ var expiryDate = nextThirdFriday.AddDays(-30);
+ var holidays = FuturesExpiryUtilityFunctions.GetExpirationHolidays(market, symbol);
+
+ // If the reference 3rd Friday is a holiday, shift expiry back one day per spec.
+ if (holidays.Contains(nextThirdFriday))
+ {
+ expiryDate = expiryDate.AddDays(-1);
+ }
+ // Ensure the computed expiry date is itself a valid tradable day.
+ while (holidays.Contains(expiryDate) || !expiryDate.IsCommonBusinessDay())
+ {
+ expiryDate = expiryDate.AddDays(-1);
+ }
+ // Trading hours for expiring VXM futures contracts end at 8:00 a.m. Chicago time on the final settlement date.
+ return expiryDate.Add(new TimeSpan(13, 0, 0));
+ })
+ },
// Bloomberg Commodity Index (AW): https://www.cmegroup.com/trading/agricultural/commodity-index/bloomberg-commodity-index_contract_specifications.html
{Symbol.Create(Futures.Indices.BloombergCommodityIndex, SecurityType.Future, Market.CBOT), (time =>
{
diff --git a/Data/future/cfe/margins/VXM.csv b/Data/future/cfe/margins/VXM.csv
new file mode 100644
index 000000000000..18a4efd5ed7e
--- /dev/null
+++ b/Data/future/cfe/margins/VXM.csv
@@ -0,0 +1,3 @@
+# we don't have historical information for this symbol
+date,initial,maintenance
+19900101,1200,960
diff --git a/Data/market-hours/market-hours-database.json b/Data/market-hours/market-hours-database.json
index 507913acf45a..db8c539cabbb 100644
--- a/Data/market-hours/market-hours-database.json
+++ b/Data/market-hours/market-hours-database.json
@@ -71632,6 +71632,124 @@
"saturday": [],
"holidays": []
},
+ "Future-cfe-VXM": {
+ "dataTimeZone": "UTC",
+ "exchangeTimeZone": "America/Chicago",
+ "sunday": [
+ {
+ "start": "17:00:00",
+ "end": "1.00:00:00",
+ "state": "premarket"
+ }
+ ],
+ "monday": [
+ {
+ "start": "00:00:00",
+ "end": "08:30:00",
+ "state": "premarket"
+ },
+ {
+ "start": "08:30:00",
+ "end": "15:00:00",
+ "state": "market"
+ },
+ {
+ "start": "15:00:00",
+ "end": "16:00:00",
+ "state": "postmarket"
+ },
+ {
+ "start": "17:00:00",
+ "end": "1.00:00:00",
+ "state": "postmarket"
+ }
+ ],
+ "tuesday": [
+ {
+ "start": "00:00:00",
+ "end": "08:30:00",
+ "state": "premarket"
+ },
+ {
+ "start": "08:30:00",
+ "end": "15:00:00",
+ "state": "market"
+ },
+ {
+ "start": "15:00:00",
+ "end": "16:00:00",
+ "state": "postmarket"
+ },
+ {
+ "start": "17:00:00",
+ "end": "1.00:00:00",
+ "state": "postmarket"
+ }
+ ],
+ "wednesday": [
+ {
+ "start": "00:00:00",
+ "end": "08:30:00",
+ "state": "premarket"
+ },
+ {
+ "start": "08:30:00",
+ "end": "15:00:00",
+ "state": "market"
+ },
+ {
+ "start": "15:00:00",
+ "end": "16:00:00",
+ "state": "postmarket"
+ },
+ {
+ "start": "17:00:00",
+ "end": "1.00:00:00",
+ "state": "postmarket"
+ }
+ ],
+ "thursday": [
+ {
+ "start": "00:00:00",
+ "end": "08:30:00",
+ "state": "premarket"
+ },
+ {
+ "start": "08:30:00",
+ "end": "15:00:00",
+ "state": "market"
+ },
+ {
+ "start": "15:00:00",
+ "end": "16:00:00",
+ "state": "postmarket"
+ },
+ {
+ "start": "17:00:00",
+ "end": "1.00:00:00",
+ "state": "postmarket"
+ }
+ ],
+ "friday": [
+ {
+ "start": "00:00:00",
+ "end": "08:30:00",
+ "state": "premarket"
+ },
+ {
+ "start": "08:30:00",
+ "end": "15:00:00",
+ "state": "market"
+ },
+ {
+ "start": "15:00:00",
+ "end": "16:00:00",
+ "state": "postmarket"
+ }
+ ],
+ "saturday": [],
+ "holidays": []
+ },
"Future-cme-E3G": {
"dataTimeZone": "UTC",
"exchangeTimeZone": "America/New_York",
diff --git a/Data/symbol-properties/symbol-properties-database.csv b/Data/symbol-properties/symbol-properties-database.csv
index ef8d02d02d67..c26555bf7532 100644
--- a/Data/symbol-properties/symbol-properties-database.csv
+++ b/Data/symbol-properties/symbol-properties-database.csv
@@ -212,6 +212,7 @@ usa,AEX,index,,EUR,1,0.01,1
# for backwards compatibility, order here is important for futures, since we could have the same symbol for more than 1 market in which case Lean will use the first
cfe,VX,future,VIX futures ,USD,1000.0,0.05,1.0
+cfe,VXM,future,VIX Mini Futures,USD,100.0,0.01,1.0
cbot,2YY,future,Micro 2-Year Yield Futures,USD,1000,0.001,1
cbot,5YY,future,Micro 5-Year Yield Futures,USD,1000,0.001,1
cbot,10Y,future,Micro 10-Year Yield Futures,USD,1000,0.001,1
diff --git a/Tests/Common/Securities/Futures/FuturesExpiryFunctionsTests.cs b/Tests/Common/Securities/Futures/FuturesExpiryFunctionsTests.cs
index e1522d91b895..4bf4d3959d91 100644
--- a/Tests/Common/Securities/Futures/FuturesExpiryFunctionsTests.cs
+++ b/Tests/Common/Securities/Futures/FuturesExpiryFunctionsTests.cs
@@ -394,6 +394,7 @@ public void FinancialsExpiryDateFunction_WithDifferentDates_ShouldFollowContract
[TestCase(QuantConnect.Securities.Futures.Indices.Russell2000EMini, NineThirtyEasternTime)]
[TestCase(QuantConnect.Securities.Futures.Indices.Nikkei225Dollar, FiveOClockPMEasternTime)]
[TestCase(QuantConnect.Securities.Futures.Indices.VIX, EightOClockChicagoTime)]
+ [TestCase(QuantConnect.Securities.Futures.Indices.VIXMini, EightOClockChicagoTime)]
[TestCase(QuantConnect.Securities.Futures.Indices.Nikkei225Yen, TwoThirtyPM)]
[TestCase(QuantConnect.Securities.Futures.Indices.MSCITaiwanIndex, OneFortyFivePM)]
[TestCase(QuantConnect.Securities.Futures.Indices.Nifty50, ThreeThirtyPM)]
diff --git a/Tests/TestData/FuturesExpiryFunctionsTestData.xml b/Tests/TestData/FuturesExpiryFunctionsTestData.xml
index 2e304b3f875e..85ed361251b9 100644
Binary files a/Tests/TestData/FuturesExpiryFunctionsTestData.xml and b/Tests/TestData/FuturesExpiryFunctionsTestData.xml differ