private Algorithm RunIteration() { // create algorithm instance to run Algorithm instanceToRun = MasterInstance.Clone(); // mark this as an optimizer run instanceToRun.IsOptimizing = true; // create result entry OptimizerResult result = new OptimizerResult(); foreach (OptimizerParam parameter in MasterInstance.OptimizerParams.Values) { result.Parameters[parameter.Name] = parameter.Value; } result.Fitness = null; Results.Add(result); // run algorithm with these values _jobQueue.QueueJob(() => { instanceToRun.Run(); result.NetAssetValue = instanceToRun.NetAssetValue[0]; result.MaxDrawdown = instanceToRun.NetAssetValueMaxDrawdown; result.Fitness = instanceToRun.FitnessValue; instanceToRun = null; lock (_optimizerLock) { _numIterationsCompleted++; TimeSpan t = DateTime.Now - _startTime; TimeSpan eta = TimeSpan.FromSeconds( (_numIterationsTotal - _numIterationsCompleted) * t.TotalSeconds / _numIterationsCompleted); _maxFitness = Math.Max(_maxFitness, (double)result.Fitness); Output.WriteLine("GridOptimizer: {0} of {1} iterations completed, max fitness = {2:F4}, eta = {3}h{4}m{5}s", _numIterationsCompleted, _numIterationsTotal, _maxFitness, Math.Floor(eta.TotalHours), eta.Minutes, eta.Seconds); } }); return(instanceToRun); }
private void RunIteration() { if (!MasterInstance.CheckParametersValid()) { // parameters are invalid. skip this iteration _numIterationsTotal--; return; } // create algorithm instance to run Algorithm instanceToRun = MasterInstance.Clone(); // mark this as an optimizer run instanceToRun.IsOptimizing = true; // create result entry OptimizerResult result = new OptimizerResult(); foreach (OptimizerParam parameter in MasterInstance.OptimizerParams.Values) { result.Parameters[parameter.Name] = parameter.Value; } result.Fitness = null; Results.Add(result); // run algorithm with these values _jobQueue.QueueJob(() => { try { // make sure to enter the extended Run method // the default implementation will forward // to the simple Run method, if required // also, we need to convert the result to a list, // in order to circumvent lazy execution var noLazyExec = instanceToRun.Run(_algoStart, _algoEnd) .ToList(); result.NetAssetValue = instanceToRun.NetAssetValue[0]; result.MaxDrawdown = instanceToRun.NetAssetValueMaxDrawdown; result.Fitness = instanceToRun.FitnessValue; instanceToRun = null; } catch (Exception e) { // we ignore any exeption while running the algo lock (_optimizerLock) { if (_verbose) { Output.WriteLine("{0}: Iteration failed. {1}", this.GetType().Name, e.Message); } } } finally { lock (_optimizerLock) { _numIterationsCompleted++; TimeSpan t = DateTime.Now - _optimizationStart; TimeSpan eta = TimeSpan.FromSeconds( (_numIterationsTotal - _numIterationsCompleted) * t.TotalSeconds / _numIterationsCompleted); if (result.Fitness != null) { _maxFitness = _maxFitness != null ? Math.Max((double)_maxFitness, (double)result.Fitness) : (double)result.Fitness; } if (_verbose) { Output.WriteLine("GridOptimizer: {0} of {1} iterations completed, max fitness = {2:F4}, eta = {3}h{4}m{5}s", _numIterationsCompleted, _numIterationsTotal, _maxFitness, Math.Floor(eta.TotalHours), eta.Minutes, eta.Seconds); } } } }); }
/// <summary> /// Run sub-classed algorithm and return bars as enumerable. /// </summary> /// <param name="startTime">start of load range</param> /// <param name="endTime">end of load range</param> /// <returns>bars created from sub-classed algo</returns> public override IEnumerable <Bar> LoadData(DateTime startTime, DateTime endTime) { #if true _algo.IsDataSource = true; if (_algo.CanRunAsChild && Info.ContainsKey(DataSourceParam.allowSync)) { // for child algorithms, we bypass the cache and run the // child bar-for-bar and in sync with its parent // we don't want to rely on the algorithm to provide a unique name. // therefore, we replace the bar symbol with the algorithm's hash var algoHashHex = string.Format("{0:X}", _algo.Name, _algo.GetHashCode()); foreach (var bar in _algo.Run(startTime, endTime)) { var bar2 = new Bar( algoHashHex, bar.Time, bar.Open, bar.High, bar.Low, bar.Close, bar.Volume, bar.HasOHLC, bar.Bid, bar.Ask, bar.BidVolume, bar.AskVolume, bar.HasBidAsk, bar.OptionExpiry, bar.OptionStrike, bar.OptionIsPut); yield return(bar2); if (!_algo.IsLastBar) { // the simulator core needs to know the next bar's // timestamp. at the same time, we want to avoid // child algorithms from running one bar ahead of // the main algo. we fix this issue by returning // a dummy bar, announcing the next timestamp. var dummy = Bar.NewValue( null, _algo.NextSimTime, 0.0); yield return(dummy); } } yield break; } else { // for all other algorithms, we run the algo // all at once and save the result in the cache var algoNick = Info[DataSourceParam.nickName]; var cacheKey = new CacheId().AddParameters( algoNick.GetHashCode(), // _algoName.GetHashCode(), startTime.GetHashCode(), endTime.GetHashCode()); List <Bar> retrievalFunction() { try { DateTime t1 = DateTime.Now; Output.WriteLine(string.Format("DataSourceAlgorithm: generating data for {0}...", Info[DataSourceParam.nickName])); var bars = _algo.Run(startTime, endTime) .ToList(); DateTime t2 = DateTime.Now; Output.WriteLine(string.Format("DataSourceAlgorithm: finished after {0:F1} seconds", (t2 - t1).TotalSeconds)); return(bars); } catch { throw new Exception("DataSourceAlgorithm: failed to run sub-classed algorithm " + algoNick); } } List <Bar> data = Cache <List <Bar> > .GetData(cacheKey, retrievalFunction, true); if (data.Count == 0) { throw new Exception(string.Format("DataSourceAlgorithm: no data for {0}", Info[DataSourceParam.nickName])); } CachedData = data; foreach (var bar in data) { yield return(bar); } } #else var algoNick = Info[DataSourceParam.nickName]; var cacheKey = new CacheId(null, "", 0, algoNick.GetHashCode(), // _algoName.GetHashCode(), startTime.GetHashCode(), endTime.GetHashCode()); List <Bar> retrievalFunction() { try { DateTime t1 = DateTime.Now; Output.WriteLine(string.Format("DataSourceAlgorithm: generating data for {0}...", Info[DataSourceParam.nickName])); _algo.StartTime = startTime; _algo.EndTime = endTime; _algo.ParentDataSource = this; _algo.SubclassedData = new List <Bar>();; _algo.Run(); DateTime t2 = DateTime.Now; Output.WriteLine(string.Format("DataSourceAlgorithm: finished after {0:F1} seconds", (t2 - t1).TotalSeconds)); return(_algo.SubclassedData); } catch { throw new Exception("DataSourceAlgorithm: failed to run sub-classed algorithm " + algoNick); } } List <Bar> data = Cache <List <Bar> > .GetData(cacheKey, retrievalFunction, true); if (data.Count == 0) { throw new Exception(string.Format("DataSourceAlgorithm: no data for {0}", Info[DataSourceParam.nickName])); } Data = data; #endif }
/// <summary> /// Run sub-classed algorithm and return bars as enumerable. /// </summary> /// <param name="startTime">start of load range</param> /// <param name="endTime">end of load range</param> /// <returns>bars created from sub-classed algo</returns> public override IEnumerable <Bar> LoadData(DateTime startTime, DateTime endTime) { #if true _algo.IsDataSource = true; if (_algo.IsChildAlgorithm) { // for child algorithms, we bypass the cache and run the // child bar-for-bar and in sync with its parent foreach (var bar in _algo.Run(startTime, endTime)) { yield return(bar); } yield break; } else { // for all other algorithms, we run the algo // all at once and save the result in the cache var algoNick = Info[DataSourceParam.nickName]; var cacheKey = new CacheId(null, "", 0, algoNick.GetHashCode(), // _algoName.GetHashCode(), startTime.GetHashCode(), endTime.GetHashCode()); List <Bar> retrievalFunction() { try { DateTime t1 = DateTime.Now; Output.WriteLine(string.Format("DataSourceAlgorithm: generating data for {0}...", Info[DataSourceParam.nickName])); var bars = _algo.Run(startTime, endTime) .ToList(); DateTime t2 = DateTime.Now; Output.WriteLine(string.Format("DataSourceAlgorithm: finished after {0:F1} seconds", (t2 - t1).TotalSeconds)); return(bars); } catch { throw new Exception("DataSourceAlgorithm: failed to run sub-classed algorithm " + algoNick); } } List <Bar> data = Cache <List <Bar> > .GetData(cacheKey, retrievalFunction, true); if (data.Count == 0) { throw new Exception(string.Format("DataSourceAlgorithm: no data for {0}", Info[DataSourceParam.nickName])); } CachedData = data; foreach (var bar in data) { yield return(bar); } } #else var algoNick = Info[DataSourceParam.nickName]; var cacheKey = new CacheId(null, "", 0, algoNick.GetHashCode(), // _algoName.GetHashCode(), startTime.GetHashCode(), endTime.GetHashCode()); List <Bar> retrievalFunction() { try { DateTime t1 = DateTime.Now; Output.WriteLine(string.Format("DataSourceAlgorithm: generating data for {0}...", Info[DataSourceParam.nickName])); _algo.StartTime = startTime; _algo.EndTime = endTime; _algo.ParentDataSource = this; _algo.SubclassedData = new List <Bar>();; _algo.Run(); DateTime t2 = DateTime.Now; Output.WriteLine(string.Format("DataSourceAlgorithm: finished after {0:F1} seconds", (t2 - t1).TotalSeconds)); return(_algo.SubclassedData); } catch { throw new Exception("DataSourceAlgorithm: failed to run sub-classed algorithm " + algoNick); } } List <Bar> data = Cache <List <Bar> > .GetData(cacheKey, retrievalFunction, true); if (data.Count == 0) { throw new Exception(string.Format("DataSourceAlgorithm: no data for {0}", Info[DataSourceParam.nickName])); } Data = data; #endif }