// -- MAIN -- public static void Main() { try { // some initialization before the start, that will depend on task execution mode chosen Initialize(); if (Shared.Config.WalkingForward.Enabled) { var wfoManager = new WalkForwardOptimizationManager(Shared.Config.StartDate, Shared.Config.EndDate, Shared.Config.FitnessScore, Shared.Config.FitnessFilter.Enabled) { WalkForwardConfiguration = Shared.Config.WalkingForward }; // register event callback wfoManager.ValidationCompleted += (sender, vdarg) => { Shared.Logger.Trace("Validation Comparsion"); Shared.Logger.Trace($"{vdarg.InsampleResults.Chromosome.Fitness} / {vdarg.ValidationResults.Chromosome.Fitness}"); Shared.Logger.Trace(" <->"); }; // and launch wfoManager.Start(); } else { // otherwise create regular optimizator var easyManager = new AlgorithmOptimumFinder( Shared.Config.StartDate, Shared.Config.EndDate, Shared.Config.FitnessScore, Shared.Config.FitnessFilter.Enabled); easyManager.Start(); } // release earlier deployed resources Dispose(); Console.WriteLine(); Console.WriteLine("Press any key to exit .. "); Console.ReadLine(); } catch (Exception e) { Shared.Logger.Trace("Main(): " + e.Message); throw; } }
/// <summary> /// Starts and continues the process till the end /// </summary> public void Start() { // Check for required config values presence if (!WalkForwardConfiguration.InSamplePeriod.HasValue || !WalkForwardConfiguration.Step.HasValue || !WalkForwardConfiguration.Anchored.HasValue) { throw new ApplicationException("WalkForwardOptimizationManager.Start(): InSamplePeriod, Step, Anchored values must be assigned"); } // Make sure that provided time frame is long enough. // We substract 1 as Lean includes the date boundaries into the backtest period var minDaysBtwStartEndRequired = WalkForwardConfiguration.InSamplePeriod.Value + WalkForwardConfiguration.Step.Value - 1; if (StartDate.AddDays(minDaysBtwStartEndRequired) > EndDate) { throw new ArgumentOutOfRangeException($"WalkForwardOptimizationManager.Start(): Provided time period [{StartDate} - {EndDate}] is short."); } // Init datetime variables will be used in first iteration var insampleStartDate = StartDate; var insampleEndDate = insampleStartDate.AddDays(WalkForwardConfiguration.InSamplePeriod.Value - 1); var validationStartDate = insampleEndDate.AddDays(1); var validationEndDate = insampleEndDate.AddDays(WalkForwardConfiguration.Step.Value); var step = WalkForwardConfiguration.Step.Value; // While insampleEndDate is less then fixed optimization EndDate we may crank one more iteration while (insampleEndDate < EndDate) { // Find optimum solutions var optimumFinder = new AlgorithmOptimumFinder(insampleStartDate, insampleEndDate, FitnessScore, _filterEnabled); optimumFinder.Start(); // Once completed retrieve N best results var n = 10; var take = optimumFinder.ProfitableChromosomes.Count > n ? n : optimumFinder.ProfitableChromosomes.Count; var bestResults = optimumFinder.ProfitableChromosomes.Take(take).ToList(); // Validate the chosen best results var validationTasks = new List <Task>(); var startDate = validationStartDate; var endDate = validationEndDate; Shared.Logger.Trace($"Taking {take} best solutions and launching the validation tasks"); Shared.Logger.Trace($"Validation period: {startDate:M/d/yy} to {endDate:M/d/yy}"); // For each good chromosome add the task to collection foreach (var c in bestResults) { var cBase = (Chromosome)c; validationTasks.Add(Task.Run(() => ValidateOutOfSample(cBase.FitnessResult, FitnessScore, startDate, endDate))); } // Wait for all tasks to complete before to continue Task.WaitAll(validationTasks.ToArray()); // Increment the variables and step to the next iteration. // If anchored do not increment insample Start Date if (!WalkForwardConfiguration.Anchored.Value) { insampleStartDate = insampleStartDate.AddDays(step); } insampleEndDate = insampleEndDate.AddDays(step); validationStartDate = validationStartDate.AddDays(step); validationEndDate = validationEndDate.AddDays(step); } }