Code for automated rollover (Part 1)

Oct 12, 2022 | EasyLanguage

Automated Rollover: Can Futures Traders Trust Continuous Contracts?

This article was written by George Pruitt and published on his blog on September 8, 2022. As we have stated in previous articles, for a Quantum Trader, understanding and programming trading systems is a common task. Here’s a code that automatically allows you to switch contracts when the time is right:

Well, you have to, don’t you?

When I was working at Futures Truth, we tested everything with our Excalibur software. This software used data from individual contracts and loaded the entire history (well, the part we kept) of each contract into memory and ran the rollovers at a certain time of the month. Excalibur had its limitations, as some futures contracts had very short histories and rollover dates had to be predetermined, ie not dynamic. Over the years, we got around the problem of short histories by creating a dynamic rolling contract that went back in time for the number of days required for a calculation. We also fixed the database with a more suitable frequency and renewal dates. So, in the end, the software simulated what I would expect from actual futures contract trading. This software was originally written in Fortran and for the Macintosh. It also had limitations in portfolio analysis, as it worked through the portfolio, one entire market at a time. Even with all these limitations, I really thought the returns were more reflective of what a trader might see in real time. Today, there aren’t many, if any, simulation platforms that do testing with individual contracts. The main reasons are the complexity of the software and the management of the database. However, if you’re willing to do the work, you can approach testing on individual contract data with EasyLanguage.

Step 1 – Get rollover dates

This is critical, as the dates will be used to exit one contract and enter another. In this post, I am going to test a simple strategy on crude oil futures. I have chosen crude because it is renewed every month. Some data providers use a specific date to renew contracts, such as Pinnacle data. In real time trading, I also did this. We had a calendar for each month and we marked rollover dates for all traded markets at the beginning of each month. The crude was renewed on the 11th or 12th of the month prior to expiration. So if we trade the September 2022 contract, we’ll do it on August 11. A single order (rollover spread) was placed to sell (if it was long) the September contract and buy the October contract in the market simultaneously. Sometimes we would rollover by executing two separate orders, hoping to get better execution. I have never been able to find a historical database of when TradeStation does its rollovers. Using the default @CL symbol allows TradeStation to use a formula to determine the best time to rollover. This is probably based on volume and open interest. TradeStation allows you to choose several different rollover triggers when your continuous data is used.

You can choose the type of activation - (3) dynamic or (4) time based

You can choose the type of activation – (3) dynamic or (4) time based

I’m getting ahead of myself, because we can just use @CL’s default data to get the renewal dates (almost). Oil is one of those rare markets where the LTD (last trading day) occurs before the FND (first day notice). Most markets warn you before a huge truck dumps 1,000 barrels of oil on your doorstep. With crude you have to be Johnny in the moment. Rollover is only a headache when trading futures, but it can be a very expensive headache if you don’t get out on time. Some markets are cash settled so rollover is not as important, but others result in commodity delivery. Most clearing companies will help you undo an expired contract for a small (relatively small) fee. They’d call you and say, “George, you’ve got to get out of that September crude soon.” Some companies would automatically settle the offending contract on your behalf, which sounds good, but could cost you. Throughout my 30 years of futures trading experience, I have been caught up in the delivery process a few times. You can determine these FND and LTD from the CME website. Below is the description of the expiration of crude oil futures.

Trading ends 3 business days before the 25th day of the month preceding the contract month. If the 25th day is not a business day, trading ends 4 business days before the 25th day of the month preceding the contract month.

You can check this on the website of your trusted broker or in the practical calendars they send at Christmas. Based on this description, the September 2022 crude contract would expire on August 20 and here is the reason:

  • August 25 is Tuesday
  • August 24 is Monday – DAY1
  • August 21 is Friday – DAY2
  • August 20 is Thursday – DAY3

This is the beauty of a well-oiled machine or bag. The FND will be produced exactly as described. All you have to do is get all the calendars for the last ten years and find the 25th day of the month and count down three business days. Or if the 25th falls on a weekend, count backwards four business days. It would be an arduous task, right? Luckily, we can have the data and an EasyLanguage script to do it for us. Take a look at this code and see if it makes any sense to you.

Case "@CL":
	If dayOfMonth(date) = 25 and firstMonthPrint = false then
	begin
		print(date[3]+19000000:8:0);
		firstMonthPrint = true;
	end;
	If(dayOfMonth(date[1]) < 25 and dayOfMonth(date) > 25 ) and firstMonthPrint = false then
	begin
		print(date[4]+19000000:8:0);
		firstMonthPrint = true;
	end;

Code to print all the FND of the crude.

I have created a tool to get the FND or LTD of any commodity future by looking at the date. In this example, I am using a Switch-Case to determine what logic is applied to the symbol on the chart. If the chart symbol is @CL, I look to see if the 25th of the month is present, and if it is, I display the date 3 days earlier. If today’s day of the month is greater than 25 and the day of the previous month is less than 25, I know that the 25th happened on a weekend and I should display the date four bars earlier. These dates are FN dates and cannot be used as is to simulate a rollover. It is better to be outside before the FND to avoid the delivery process. The rollover date on Pinnacle Crude is the 11th of the previous month for continuous crude contracts. I aimed at this day of the month with my logic. If the FND normally fell on the 22nd of the month, then I would need to move back 9 or 10 business days to get closer to the 11th of the month. I also wanted to use the output directly with an EasyLanguage strategy so I modified my output to be exact EasyLanguage.

Case "@CL":
	If dayOfMonth(date) = 25 and firstMonthPrint = false then 
	begin
	value1 = value1 + 1;
		print("rollArr[",value1:1:0,"]=",date[9]+19000000:8:0,";");
		firstMonthPrint = true;
	end;
	If(dayOfMonth(date[1]) < 25 and dayOfMonth(date) > 25 ) and firstMonthPrint = false then
	begin
		value1 = value1 + 1;
		print("rollArr[",value1:1:0,"]=",date[10]+19000000:8:0,";");
//		print(date[4]+19000000:8:0);
		firstMonthPrint = true;
	end;


// example of output

rollArr[103]=20210312;
rollArr[104]=20210412;
rollArr[105]=20210512;
rollArr[106]=20210614;
rollArr[107]=20210712;
rollArr[108]=20210812;
rollArr[109]=20210913;
rollArr[110]=20211012;
rollArr[111]=20211111;
rollArr[112]=20211210;
rollArr[113]=20220111;
rollArr[114]=20220211;
rollArr[115]=20220314;
rollArr[116]=20220411;
rollArr[117]=20220512;
rollArr[118]=20220610;
rollArr[119]=20220712;
rollArr[120]=20220812;

Code to print our 9 or 10 bars before FND in the current EasyLanguage

Now that I had the theoretical rollover dates for my analysis, I needed to make sure that the data I was going to use matched exactly. As you’ve seen before, you can choose the rollover date for your chart data. And you can also determine the adjustment to be added or subtracted from all previous values, based on the difference between the closing prices at the time of the date change. I played around with the number of days prior to FND and selected unadjusted for the smoothing of the prior data.

Real data with which I have simulated the rollovers

Real data with which I have simulated the rollovers

How did I determine that it is 8 days before the first notification date? I plotted different data using a different number of days prior and determined that 8 provided a sweet spot between the open interest of the old and new contract data. Can you see the rollover points in the graph below? Ignore operations – this is a beta test.

The Open Interest Valley is the rollover date

The Open Interest Valley is the rollover date

The dates when open interest creates a trough lined up very closely with the dates I had printed using my FND date lookup function. To be sure, I compared the dates and arranged the data in my matrix to exactly match the chart. Here are two rollover operations – they are now correct.

Using a continuous tight contract you would not see these trades

Using a continuous tight contract you would not see these trades

This post turned out to be a bit longer than I thought, so I’ll post the results of using an adjusted rolling contract with no rollovers, and the results using unadjusted concatenated contracts with rollovers. The strategy will be a simple 40/20 bar Donchian entry/exit. You may be surprised by the results – stay tuned.

Article courtesy of George Pruitt

To read our next article on Part 2, click this link: Can Futures Traders Trust Continuous Contracts? [Part 2]

If you want to see part of the code that has been used in this article, we have it available for anyone who wants it, to request it click on this link: Contact

Quantified Models Youtube Channel

On our YouTube channel we have several videos available that you may find very useful for developing trading systems. To access, click this link: Quantified Models YouTube Channel

We hope this information has been useful to you.

Subscribe to our Newsletter

Join our mailing list to receive the latest news and updates from Quantified Models team.

Subscribe to our Newsletter

You have Successfully Subscribed!

Skip to content