- ago
I run optimizations on over 15 years of unfiltered 5-minute bars and rely heavily on TimeSeriesSynchronizer.Synchronize (called 9 times per run). Since my code is slow to initialize, it produces incorrect optimization results—even when using Exhaustive (non-parallel) mode.

After tracing the issue, I found the problem originates from TimeSeriesSynchronizer.Synchronize.

Would it be possible to provide a non-static version of TimeSeriesSynchronizer.Synchronize?


0
89
5 Replies

Reply

Bookmark

Sort
Glitch8
 ( 9.81% )
- ago
#1
I can't see how that would be an issue. I just double checked, and TimeSeriesSynchronizer doesn't use any class level variables. It only uses local variables in the Synchronize method. So, there should be no issue calling it in a multi-threaded context.
0
- ago
#2
Gemini AI wrote this replacement for me. I will try it and see if it fixes the issue
CODE:
// In a file like Trade.Helper.cs /// <summary> /// A thread-safe, instance-based replacement for the static TimeSeriesSynchronizer.Synchronize method. /// This function takes a "sparse" source series (e.g., calculated on RTH-only bars) and /// creates a new "dense" series that is aligned to the main 24-hour chart, filling /// any gaps by carrying forward the last known value. /// </summary> /// <param name="sourceSeries">The sparse TimeSeries to be synchronized.</param> /// <param name="targetBars">The dense, master BarHistory to align to.</param> /// <returns>A new, dense TimeSeries that is safe for parallel processing.</returns> private TimeSeries CreateSynchronizedTimeSeries(TimeSeries sourceSeries, BarHistory targetBars) { // 1. Handle edge cases for safety. if (sourceSeries == null || targetBars == null || sourceSeries.Count == 0) { return new TimeSeries(targetBars.DateTimes, 0.0); // Return an empty/zeroed series. } // 2. For performance, build a dictionary for fast timestamp lookups from the source. var sourceValues = new Dictionary<DateTime, double>(); for (int i = 0; i < sourceSeries.Count; i++) { // The source series might have duplicate timestamps if not careful; this handles it. sourceValues[sourceSeries.DateTimes[i]] = sourceSeries[i]; } // 3. Create the new series that will hold the synchronized result. var synchronizedSeries = new TimeSeries(targetBars.DateTimes, 0.0); double lastKnownValue = 0.0; // Start with a default value. Could also use sourceSeries[0]. // 4. Loop through the master (dense) timeline and build the new series. for (int i = 0; i < targetBars.Count; i++) { DateTime currentTimestamp = targetBars.DateTimes[i]; // Check if our source data has a value for this exact timestamp. if (sourceValues.TryGetValue(currentTimestamp, out double newValue)) { // A new value exists. Use it and update our "last known" value. synchronizedSeries[i] = newValue; lastKnownValue = newValue; } else { // No new value exists for this timestamp (it's a gap). // Fill the gap by carrying forward the last known value. synchronizedSeries[i] = lastKnownValue; } } return synchronizedSeries; }
0
- ago
#3
QUOTE:
it produces incorrect optimization results—even when using Exhaustive (non-parallel) mode.

If that's true, then how would a non-static method work any better?

There may be some kind of a problem with the data structures getting corrupted somehow, but if you're in non-parallel mode, it's not multiple strategy threads colliding with each other. We certainly know that.

If optimization fails in non-parallel mode, then what's your theory on how the data structures are getting corrupted since only one execution thread is involved? And why would you be calling TimeSeriesSynchronizer.Synchronize more than once on the same time series? (Or am I missing something important?) Was this a problem under WL6?

Personally, I don't have any problems with the optimization step, but then I'm not calling TimeSeriesSynchronizer.Synchronize in any of my strategies either.
0
- ago
#4
I noted that the issue also occurred in non-parallel mode, which didn’t make sense to me. However, after replacing the method with the code above, the problem no longer reproduced.
1
Cone8
 ( 20.40% )
- ago
#5
Re: CreateSynchronizedTimeSeries()
Pretty slick, but it will probably work properly only for two intraday series. It will absolutely not synchronize correctly between daily and intraday (if at all). For that to work, you'd first need to duplicate the Daily+ series with new timestamps, adding the TimeOfDay of the close.
0

Reply

Bookmark

Sort