QuantConnect/Lean · error · RegressionTestException
The time zone of security {secondCustomSecurity} should be {
Error message
The time zone of security {secondCustomSecurity} should be {TimeZones.Utc}, but it was {secondCustomSecurity.Exchange.TimeZone} What it means
Same integrity check as the first security, applied to the second custom-data security built on an Oanda EURUSD symbol. After AddData<ExampleCustomData>(market2.Symbol, Resolution.Hour, TimeZones.Utc, false), secondCustomSecurity.Exchange.TimeZone must be Utc. The test deliberately registers the same custom type on two different market variants to ensure each keeps its own supplied zone.
Source
Thrown at Algorithm.CSharp/CustomDataWorksWithDifferentExchangesRegressionAlgorithm.cs:45
{
private bool _noDataPointsReceived;
public override void Initialize()
{
SetStartDate(2014, 05, 02);
SetEndDate(2014, 05, 03);
var market1 = AddForex("EURUSD", Resolution.Hour, Market.FXCM);
var firstCustomSecurity = AddData<ExampleCustomData>(market1.Symbol, Resolution.Hour, TimeZones.Utc, false);
if (firstCustomSecurity.Exchange.TimeZone != TimeZones.Utc)
{
throw new RegressionTestException($"The time zone of security {firstCustomSecurity} should be {TimeZones.Utc}, but it was {firstCustomSecurity.Exchange.TimeZone}");
}
var market2 = AddForex("EURUSD", Resolution.Hour, Market.Oanda);
var secondCustomSecurity = AddData<ExampleCustomData>(market2.Symbol, Resolution.Hour, TimeZones.Utc, false);
if (secondCustomSecurity.Exchange.TimeZone != TimeZones.Utc)
{
throw new RegressionTestException($"The time zone of security {secondCustomSecurity} should be {TimeZones.Utc}, but it was {secondCustomSecurity.Exchange.TimeZone}");
}
_noDataPointsReceived = true;
}
public override void OnData(Slice slice)
{
_noDataPointsReceived = false;
if (slice.Count != ActiveSecurities.Count)
{
throw new RegressionTestException($"{ActiveSecurities.Count.ToString().ToCamelCase()} data points were expected, but only {slice.Count} were received");
}
}
public override void OnEndOfAlgorithm()
{
if (_noDataPointsReceived)
{View on GitHub (pinned to d2c3659f87)
Solutions
- Ensure each AddData call builds an independent SubscriptionDataConfig with its own ExchangeTimeZone rather than reusing the first security's config.
- Confirm the Oanda forex symbol is treated as distinct from the FXCM one (different SID/market) so its custom data config is independent.
- Inspect SubscriptionManager to confirm no dedup collapses the two custom-data securities into one.
- Re-run with logging on config creation to verify both zones are stored as Utc.
Example fix
// before: second AddData reuses first security's config/zone var secondCustomSecurity = AddData<ExampleCustomData>(market2.Symbol, Resolution.Hour, false, false); // after: independent config with its own Utc zone var secondCustomSecurity = AddData<ExampleCustomData>(market2.Symbol, Resolution.Hour, TimeZones.Utc, false);
Defensive patterns
Strategy: validation
Validate before calling
var s2 = AddData<ExampleCustomData>(market2.Symbol, Resolution.Hour, TimeZones.Utc, false);
if (s2.Exchange.TimeZone != TimeZones.Utc)
throw new InvalidOperationException($"Second security zone mismatch: {s2.Exchange.TimeZone}"); Type guard
bool ConfigsAreIndependent(Security a, Security b) => !ReferenceEquals(a.Subscriptions.First(), b.Subscriptions.First());
Prevention
- Treat each AddData call as independent; assert each security keeps its supplied zone.
- When adding the same custom type across markets, verify SubscriptionDataConfigs are not deduplicated.
- Log config.ExchangeTimeZone at registration to catch silent reuse.
When it happens
Trigger: Registering custom data on a second market (Oanda) of an already-added symbol and reading Exchange.TimeZone; it inherits the first security's zone or the market default instead of Utc.
Common situations: Symbol/Security sharing logic that caches one exchange-zone per underlying ticker; AddData not isolating config per market; or a refactor that merged configs across markets.
Related errors
- The time zone of security {firstCustomSecurity} should be {T
- The ticker did not rename throughout the course of its life
- {ActiveSecurities.Count.ToString().ToCamelCase()} data point
- No points were received
- Custom data was not received
AI-assisted analysis of QuantConnect/Lean@d2c3659f87 (2026-08-13).
Data as JSON: /api/errors/a8a1299cdfa3aaca.
Report an issue: GitHub.