Skip to content

Commit 261366a

Browse files
Ruuudy1claude
andauthored
Add VIX Mini Futures (VXM) Support (#9400)
* Add VIX Mini Futures (VXM) support Adds complete LEAN support for VIX Mini Futures (VXM) traded on CBOE: - Add Futures.Indices.VIXMini = "VXM" constant - Add expiry function: 30 days before third Friday of following month - Add symbol properties: multiplier 100, tick 0.01 (USD) - Add 15 test date pairs for 2023-2025 to FuturesExpiryFunctionsTestData.xml - Add [TestCase(VIXMini, EightOClockChicagoTime)] to IndicesExpiryDateFunction test - Add market hours configuration mirroring VX trading hours Closes #6655 Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * Fix VXM expiry holiday validation and add margin file - Replace single `if` holiday check with `while` loop using `IsCommonBusinessDay()` to ensure the computed expiry date is always a valid tradable day (not just one step back) - Fix test data: 2025-03-19 -> 2025-03-18 (April 18 2025 is Good Friday, a CFE holiday, shifting the expiry back) - Add Data/future/cfe/margins/VXM.csv margin file Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
1 parent 932fb7e commit 261366a

7 files changed

Lines changed: 154 additions & 0 deletions

File tree

Common/Securities/Future/Futures.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1388,6 +1388,12 @@ public static class Indices
13881388
/// <returns>The symbol</returns>
13891389
public const string VIX = "VX";
13901390

1391+
/// <summary>
1392+
/// VIX Mini Futures
1393+
/// </summary>
1394+
/// <returns>The symbol</returns>
1395+
public const string VIXMini = "VXM";
1396+
13911397
/// <summary>
13921398
/// E-mini Russell 2000 Futures
13931399
/// </summary>

Common/Securities/Future/FuturesExpiryFunctions.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,31 @@ public static Func<DateTime, DateTime> FuturesExpiryFunction(Symbol symbol)
543543
return expiryDate.Add(new TimeSpan(13, 0, 0));
544544
})
545545
},
546+
// VIX Mini Futures (VXM): https://cdn.cboe.com/resources/futures/VXM_Contract_Specifications.pdf
547+
{Symbol.Create(Futures.Indices.VIXMini, SecurityType.Future, Market.CFE), (time =>
548+
{
549+
// Trading occurs 30 days before S&P 500 option expiration (third Friday of contract month).
550+
// Last trading day is the Wednesday 30 days prior to the third Friday of the contract month.
551+
var market = Market.CFE;
552+
var symbol = Futures.Indices.VIXMini;
553+
var nextThirdFriday = FuturesExpiryUtilityFunctions.ThirdFriday(time.AddMonths(1));
554+
var expiryDate = nextThirdFriday.AddDays(-30);
555+
var holidays = FuturesExpiryUtilityFunctions.GetExpirationHolidays(market, symbol);
556+
557+
// If the reference 3rd Friday is a holiday, shift expiry back one day per spec.
558+
if (holidays.Contains(nextThirdFriday))
559+
{
560+
expiryDate = expiryDate.AddDays(-1);
561+
}
562+
// Ensure the computed expiry date is itself a valid tradable day.
563+
while (holidays.Contains(expiryDate) || !expiryDate.IsCommonBusinessDay())
564+
{
565+
expiryDate = expiryDate.AddDays(-1);
566+
}
567+
// Trading hours for expiring VXM futures contracts end at 8:00 a.m. Chicago time on the final settlement date.
568+
return expiryDate.Add(new TimeSpan(13, 0, 0));
569+
})
570+
},
546571
// Bloomberg Commodity Index (AW): https://www.cmegroup.com/trading/agricultural/commodity-index/bloomberg-commodity-index_contract_specifications.html
547572
{Symbol.Create(Futures.Indices.BloombergCommodityIndex, SecurityType.Future, Market.CBOT), (time =>
548573
{

Data/future/cfe/margins/VXM.csv

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# we don't have historical information for this symbol
2+
date,initial,maintenance
3+
19900101,1200,960

Data/market-hours/market-hours-database.json

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71632,6 +71632,124 @@
7163271632
"saturday": [],
7163371633
"holidays": []
7163471634
},
71635+
"Future-cfe-VXM": {
71636+
"dataTimeZone": "UTC",
71637+
"exchangeTimeZone": "America/Chicago",
71638+
"sunday": [
71639+
{
71640+
"start": "17:00:00",
71641+
"end": "1.00:00:00",
71642+
"state": "premarket"
71643+
}
71644+
],
71645+
"monday": [
71646+
{
71647+
"start": "00:00:00",
71648+
"end": "08:30:00",
71649+
"state": "premarket"
71650+
},
71651+
{
71652+
"start": "08:30:00",
71653+
"end": "15:00:00",
71654+
"state": "market"
71655+
},
71656+
{
71657+
"start": "15:00:00",
71658+
"end": "16:00:00",
71659+
"state": "postmarket"
71660+
},
71661+
{
71662+
"start": "17:00:00",
71663+
"end": "1.00:00:00",
71664+
"state": "postmarket"
71665+
}
71666+
],
71667+
"tuesday": [
71668+
{
71669+
"start": "00:00:00",
71670+
"end": "08:30:00",
71671+
"state": "premarket"
71672+
},
71673+
{
71674+
"start": "08:30:00",
71675+
"end": "15:00:00",
71676+
"state": "market"
71677+
},
71678+
{
71679+
"start": "15:00:00",
71680+
"end": "16:00:00",
71681+
"state": "postmarket"
71682+
},
71683+
{
71684+
"start": "17:00:00",
71685+
"end": "1.00:00:00",
71686+
"state": "postmarket"
71687+
}
71688+
],
71689+
"wednesday": [
71690+
{
71691+
"start": "00:00:00",
71692+
"end": "08:30:00",
71693+
"state": "premarket"
71694+
},
71695+
{
71696+
"start": "08:30:00",
71697+
"end": "15:00:00",
71698+
"state": "market"
71699+
},
71700+
{
71701+
"start": "15:00:00",
71702+
"end": "16:00:00",
71703+
"state": "postmarket"
71704+
},
71705+
{
71706+
"start": "17:00:00",
71707+
"end": "1.00:00:00",
71708+
"state": "postmarket"
71709+
}
71710+
],
71711+
"thursday": [
71712+
{
71713+
"start": "00:00:00",
71714+
"end": "08:30:00",
71715+
"state": "premarket"
71716+
},
71717+
{
71718+
"start": "08:30:00",
71719+
"end": "15:00:00",
71720+
"state": "market"
71721+
},
71722+
{
71723+
"start": "15:00:00",
71724+
"end": "16:00:00",
71725+
"state": "postmarket"
71726+
},
71727+
{
71728+
"start": "17:00:00",
71729+
"end": "1.00:00:00",
71730+
"state": "postmarket"
71731+
}
71732+
],
71733+
"friday": [
71734+
{
71735+
"start": "00:00:00",
71736+
"end": "08:30:00",
71737+
"state": "premarket"
71738+
},
71739+
{
71740+
"start": "08:30:00",
71741+
"end": "15:00:00",
71742+
"state": "market"
71743+
},
71744+
{
71745+
"start": "15:00:00",
71746+
"end": "16:00:00",
71747+
"state": "postmarket"
71748+
}
71749+
],
71750+
"saturday": [],
71751+
"holidays": []
71752+
},
7163571753
"Future-cme-E3G": {
7163671754
"dataTimeZone": "UTC",
7163771755
"exchangeTimeZone": "America/New_York",

Data/symbol-properties/symbol-properties-database.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ cboe,[*],index,,USD,1,0.01,1
214214

215215
# 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
216216
cfe,VX,future,VIX futures ,USD,1000.0,0.05,1.0
217+
cfe,VXM,future,VIX Mini Futures,USD,100.0,0.01,1.0
217218
cbot,2YY,future,Micro 2-Year Yield Futures,USD,1000,0.001,1
218219
cbot,5YY,future,Micro 5-Year Yield Futures,USD,1000,0.001,1
219220
cbot,10Y,future,Micro 10-Year Yield Futures,USD,1000,0.001,1

Tests/Common/Securities/Futures/FuturesExpiryFunctionsTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ public void FinancialsExpiryDateFunction_WithDifferentDates_ShouldFollowContract
394394
[TestCase(QuantConnect.Securities.Futures.Indices.Russell2000EMini, NineThirtyEasternTime)]
395395
[TestCase(QuantConnect.Securities.Futures.Indices.Nikkei225Dollar, FiveOClockPMEasternTime)]
396396
[TestCase(QuantConnect.Securities.Futures.Indices.VIX, EightOClockChicagoTime)]
397+
[TestCase(QuantConnect.Securities.Futures.Indices.VIXMini, EightOClockChicagoTime)]
397398
[TestCase(QuantConnect.Securities.Futures.Indices.Nikkei225Yen, TwoThirtyPM)]
398399
[TestCase(QuantConnect.Securities.Futures.Indices.MSCITaiwanIndex, OneFortyFivePM)]
399400
[TestCase(QuantConnect.Securities.Futures.Indices.Nifty50, ThreeThirtyPM)]
4.52 KB
Binary file not shown.

0 commit comments

Comments
 (0)