/// <summary> /// Evaluates the chromosome's fitness. /// </summary> public override async Task EvaluateAsync(IChromosome chromosome) { try { // cast to the base type var chromosomeBase = (Chromosome)chromosome; // Convert to dictionary and add "id" key-value pair var list = chromosomeBase.ToDictionary(); list.Add("chromosome-id", chromosomeBase.Id); // Set algorithm start and end dates list.Add("start-date", StartDate.ToString("O")); list.Add("end-date", EndDate.ToString("O")); // Additional settings to the list list.Add("algorithm-type-name", Shared.Config.AlgorithmTypeName); list.Add("algorithm-location", Shared.Config.AlgorithmLocation); list.Add("data-folder", Shared.Config.DataFolder); // Obtain full results var result = await Task.Run(() => AppDomainRunner.RunAlgorithm(list)); // Calculate fitness and concat the results with an output string var fitness = StatisticsAdapter.CalculateFitness(result, FitnessScore, FilterEnabled); // Save full results chromosomeBase.FitnessResult = new FitnessResult { Chromosome = chromosomeBase, StartDate = this.StartDate, EndDate = this.EndDate, FullResults = result }; // create an output string var theOutput = chromosomeBase.EvaluationToLogOutput(result, FitnessScore, fitness); // Display the output lock (_lock) { Shared.Logger.Trace(theOutput + Environment.NewLine); } // assign a value to chromosome fitness chromosome.Fitness = fitness; } catch (Exception ex) { Shared.Logger.Error("OptimizerFitness.Evaluate: " + ex.Message); } }
/// <summary> /// Async evalutation. /// </summary> public override async Task EvaluateAsync(IChromosome chromosome) { // Cast to base chromosome type var chromosomeBase = (Chromosome)chromosome; // Application Package Directory string appPath = $"%AZ_BATCH_APP_PACKAGE_{AzureBatchManager.AppPackageId}#{AzureBatchManager.AppPackageVersion}%"; // Chromosome's unique identifier var id = chromosomeBase.Id; // -- 1 -- Create an argument string of gene key-values var runnerInputArguments = chromosomeBase.ToKeyValueString() + " "; // -- 2 -- Add an algorithm name to that string runnerInputArguments += $"algorithm-type-name {Shared.Config.AlgorithmTypeName} "; // -- 3 -- Add algorithm dll and data folder locations var dllFileName = Path.GetFileName(Shared.Config.AlgorithmLocation); runnerInputArguments += $"algorithm-location %AZ_BATCH_NODE_STARTUP_DIR%\\wd\\{dllFileName} "; runnerInputArguments += $"data-folder {AzureBatchManager.DataNetDrive} "; // -- 4 -- Algorithm start and end dates runnerInputArguments += $"start-date {StartDate:O} "; runnerInputArguments += $"end-date {EndDate:O} "; // -- 5 -- File name where the final result of a backtest will be stored at. var resultsOutputFile = $"output_{id}.json"; runnerInputArguments += $"results-output {resultsOutputFile} "; // -- 6 -- File name for Lean logs var leanLogFile = $"log_{id}.txt"; runnerInputArguments += $"log-file {leanLogFile}"; // Now using all arguments construct the resulting command line string string fileShareUncPath = $"\\\\{AzureBatchManager.DataFileShare.Uri.Host}\\{AzureBatchManager.DataFileShare.Name}"; string cmdMapNetDrive = $"net use {AzureBatchManager.DataNetDrive} {fileShareUncPath}"; string cmdRunner = $"{appPath}\\Debug\\Optimization.RunnerAppAzure.exe {runnerInputArguments}"; string taskCommandLine = $"cmd /c \"{cmdMapNetDrive} & {cmdRunner}\""; // Create task id. Create a cloud task. var taskId = $"task_{id}"; CloudTask cloudTask = new CloudTask(taskId, taskCommandLine) { UserIdentity = new UserIdentity(new AutoUserSpecification( elevationLevel: ElevationLevel.NonAdmin, scope: AutoUserScope.Pool)) }; // After app package finishes work and exits the Files: // Task output file and lean log will be automatically uploaded to the output blob container in Azure Storage. List <OutputFile> outputFileList = new List <OutputFile>(); // #1 OutputFile outputFileA = new OutputFile(resultsOutputFile, new OutputFileDestination( new OutputFileBlobContainerDestination(AzureBatchManager.OutputContainerSasUrl, path: @"results\" + resultsOutputFile)), new OutputFileUploadOptions(OutputFileUploadCondition.TaskSuccess)); // #2 OutputFile outputFileB = new OutputFile(leanLogFile, new OutputFileDestination( new OutputFileBlobContainerDestination(AzureBatchManager.OutputContainerSasUrl, path: @"logs\" + leanLogFile)), new OutputFileUploadOptions(OutputFileUploadCondition.TaskSuccess)); // Add Output Files to the list outputFileList.Add(outputFileA); outputFileList.Add(outputFileB); // Assign the list to cloud task's OutputTask property cloudTask.OutputFiles = outputFileList; // Create a collection to hold the tasks added to the job and add our task to that colleation. var cloudTaskCollection = new List <CloudTask> { cloudTask }; // Azure Cloud objects var batchClient = AzureBatchManager.BatchClient; var blobClient = AzureBatchManager.BlobClient; var jobId = AzureBatchManager.JobId; // Call BatchClient.JobOperations.AddTask() to add the tasks as a collection to a queue await batchClient.JobOperations.AddTaskAsync(jobId, cloudTaskCollection); // Monitor for a task to complete. Timeout is set as a class's constant variable. await MonitorSpecificTaskToCompleteAsync(batchClient, jobId, taskId, TimeOutForTaskToComplete); // Obtain results dictionary var result = await ObtainResultFromTheBlob(blobClient, AzureBatchManager.OutputContainerName, @"results\" + resultsOutputFile); // Calculate fitness var fitness = StatisticsAdapter.CalculateFitness(result, FitnessScore, FilterEnabled); // Save full results chromosomeBase.FitnessResult = new FitnessResult { Chromosome = chromosomeBase, StartDate = this.StartDate, EndDate = this.EndDate, FullResults = result }; var logOutput = chromosomeBase.EvaluationToLogOutput(result, FitnessScore, fitness); // Display the output lock (_lock) { Shared.Logger.Trace(logOutput + Environment.NewLine); } // Assign fitness value to a chromosome chromosome.Fitness = fitness; }