IQFeed and stock splits

Using Amibroker 6.93.

As we know IQFeed does not split adjust their intraday data, so I understand that I need to do that manually. However when I do that, save and close, and then reopen Amibroker, it creates a new problem:

The most recent stock split is undone for trailing 5 days, but data before that retains split adjustment. This happens even if I force backfill and redo all of the stock split adjustments and save the database again. After about a week this problem will generally go away and all of the split adjustments will finally stick.

This also happens if I disconnect IQFeed plugin, do the split adjustments, and then reconnect IQFeed. Upon reconnection IQFeed will overwrite the most recent week of data with nonadjusted data. Please advise, thanks!

As you correctly noted, IQFeed does not split adjust intraday data.
That is the source of the problem and the only way to fix it for good is convincing IQFeed that they should split adjust AT THE SOURCE.

Adjusting afterwards is problematic because while obviously you can do this in AmiBroker, it only affects data stored locally (not what is on IQFeed server side).

Now when you backfill again from IQFeed, you will get again UNADJUSTED data.
Why you get this few bars bad.
This so because backfill (that happens if you download missing data) downloads from most recent update to "now", plus few bars extra (to cover corrections). That "extra" might create anomaly.

To fix that you have to "FORCE BACKFILL" (to re-backfill EVERYTHING from the start, unadjusted data from IQFeed) and then do SPLIT correction in AmiBroker.

The problem persists even after FORCE BACKFILL and SPLIT adjustment. As soon as Amibroker opens up and IQFeed connects it will undo the adjustment only for the most recent 5 days. This can be reproduced with a recent stock of symbol BOIL. Split adjustment -> IQFeed disconnect -> IQFeed reconnect yields the same issue.

I need to close and reopen Amibroker daily to make sure the IQFeed connection doesn't run stale, as I have run into issues with that before. But as soon as IQFeed reconnects it undoes my split adjustment.

Yes, because on re-opening, IQFeed plugin must fill missing data. And it fills slightly more because last existing bars, might receive late corrections (data feeds and exchange send corrections after the time). As I wrote, data vendor charges you money to deliver data and their duty is to deliver them in correct way. In this case it would be split adjusted at the source.

Okay, so I understand that the issue is that because

  1. They refuse to split adjust intraday data
  2. Upon reconnection the plugin asks for corrections to recent data, and forcefully overwrites

Where do we go from here? I have asked them more than once for split adjusted intraday data over the years and they are refusing to deliver it. Here aretheir most recent tech support replies:

"Unfortunately, we do not adjust intraday data for splits. The only way to avoid the "correcting" would be to not redownload history after you have corrected it. "

"It looks like you are connecting to Amibroker. You will need to contact Amibroker support to see if they have a way to limit how much history is getting loaded. There are no settings for this in the IQFeed client that will affect how Amibroker saves history data."

Esignal is 3x the price, and from what I am reading even they do not provide split adjusted intraday data.

Do I have to write some kind of script to automatically "un-correct" their "corrections?" Reading through past threads, would it be best to go through OLE to do this programmatically? Threads:

Ended up making a custom function where I can manually enter dates and ratios:

// Function to manually enter split adjusted dates and ratios for symbol. -dude 2026-06-02

function splitAdjust(input) {
local dn,sym,splitFactor,priceAdj;

dn = DateNum();
sym = Name();
splitFactor = 1;

	if (sym == "TQQQ") {
	splitFactor = 
		  IIf(dn < 1251120, 1/2, 1)		// November 20, 2025: 2-for-1 split
		* IIf(dn < 1220113, 1/2, 1)		// January 13, 2022: 2-for-1 split
		* IIf(dn < 1210121, 1/2, 1)		// January 21, 2021: 2-for-1 split
		* IIf(dn < 1180524, 1/3, 1)		// May 24, 2018: 3-for-1 split
		* IIf(dn < 1170112, 1/2, 1)		// January 12, 2017: 2-for-1 split
		* IIf(dn < 1140124, 1/2, 1)		// January 24, 2014: 2-for-1 split
		* IIf(dn < 1120511, 1/2, 1)		// May 11, 2012: 2-for-1 split
		* IIf(dn < 1110225, 1/2, 1)		// February 25, 2011: 2-for-1 split
		;
	}

	if (sym == "TECL") {
	splitFactor = 
		  IIf(dn < 1210302, 1/10, 1)	// March 2, 2021: 10-for-1 forward split
		* IIf(dn < 1150520, 1/4, 1)		// May 20, 2015: 4-for-1 forward split
		* IIf(dn < 1100505, 1/4, 1)		// May 5, 2010: 4-for-1 forward split
		;
	}


priceAdj = input * splitFactor;

return priceAdj;
}