private static void EvaluateStrategy( int numberOfAccounts, int accountId, EvaluationResultContextManager contextManager, ITradingStrategy strategy, IDictionary <ParameterAttribute, object> parameterValues, DateTime startDate, DateTime endDate, ICapitalManager capitalManager, ITradingDataProvider dataProvider, StockBlockRelationshipManager relationshipManager, bool shouldDumpData, TradingSettings tradingSettings) //StockNameTable stockNameTable) { // OutputParameterValues(parameterValues); EvaluationResultContext context; lock (contextManager) { context = contextManager.CreateNewContext(); } using (context) { StreamWriter dumpDataWriter = shouldDumpData ? context.DumpDataWriter : null; var evaluator = new TradingStrategyEvaluator( numberOfAccounts, accountId, capitalManager, strategy, parameterValues, dataProvider, relationshipManager, tradingSettings, context.Logger, dumpDataWriter); //EventHandler<EvaluationProgressEventArgs> evaluationProgressHandler = // (object obj, EvaluationProgressEventArgs e) => // { // Console.Write("\r{0:yyyy-MM-dd} {1}%", e.EvaluationPeriod, (int)(e.EvaluationPercentage * 100.0)); // }; //evaluator.OnEvaluationProgress += evaluationProgressHandler; try { evaluator.Evaluate(); } catch (Exception ex) { Console.WriteLine(); Console.WriteLine("{0}", ex); return; } if (!evaluator.Tracker.TransactionHistory.Any()) { // no transaction return; } var calculator = new TradeMetricsCalculator( //stockNameTable, evaluator.Tracker, dataProvider, tradingSettings); var metrics = calculator.Calculate(); // get the overall metric var tradeMetrics = metrics as TradeMetric[] ?? metrics.ToArray(); var overallMetric = tradeMetrics.First(m => m.Code == TradeMetric.CodeForAll); // summarize block related data BlockTradingDetailSummarizer summarizer = new BlockTradingDetailSummarizer(evaluator.Tracker, dataProvider); var details = summarizer.Summarize(); // save results context.SaveResults(parameterValues, tradeMetrics, evaluator.ClosedPositions, details); // create result summary; var resultSummary = new ResultSummary(); resultSummary.Initialize( context, parameterValues, startDate, endDate, overallMetric); lock (contextManager) { contextManager.AddResultSummary(resultSummary); } } }
static void Run(Options options) { // check the validation of options CheckOptions(options); // generate example files if necessary if (options.ShouldGenerateExampleFiles) { GenerateExampleFiles(options); return; } // register handler for Ctrl+C/Ctrl+Break Console.CancelKeyPress += ConsoleCancelKeyPress; // load settings from files var tradingSettings = TradingSettings.LoadFromFile(options.TradingSettingsFile); var combinedStrategySettings = CombinedStrategySettings.LoadFromFile(options.CombinedStrategySettingsFile); var stockDataSettings = ChinaStockDataSettings.LoadFromFile(options.StockDataSettingsFile); // load codes and stock name table var stockNameTable = new StockNameTable(stockDataSettings.StockNameTableFile); var codes = LoadCodeOfStocks(options.CodeFile); // load stock block relationship if necessary, and filter codes StockBlockRelationshipManager stockBlockRelationshipManager = null; if (!string.IsNullOrWhiteSpace(options.StockBlockRelationshipFile)) { stockBlockRelationshipManager = LoadStockBlockRelationship(options.StockBlockRelationshipFile); // filter stock block relationship for loaded codes only stockBlockRelationshipManager = stockBlockRelationshipManager.CreateSubsetForStocks(codes); // codes will be updated according to stock-block relationships codes = stockBlockRelationshipManager.Stocks; } var allDataFiles = codes .Select(stockDataSettings.BuildActualDataFilePathAndName) .ToArray(); // dump data for temporary usage, will be commented out in real code // create data provider //var dumpDataProvider // = new ChinaStockDataProvider( // stockNameTable, // allDataFiles, // options.StartDate, // options.EndDate, // 0); //DumpData(dumpDataProvider); // generate evaluation time intervals var intervals = GenerateIntervals( options.StartDate, options.EndDate, options.YearInterval) .ToArray(); using (_contextManager = new EvaluationResultContextManager(options.EvaluationName)) { // save evluation summary var evaluationSummary = new EvaluationSummary { StrategySettings = combinedStrategySettings.GetActiveSettings(), TradingSettings = tradingSettings, DataSettings = stockDataSettings, StartTime = options.StartDate, EndTime = options.EndDate, YearInterval = options.YearInterval, ObjectNames = codes .Select(c => stockNameTable.ContainsStock(c) ? c + '|' + stockNameTable[c].Names[0] : c) .ToArray() }; _contextManager.SaveEvaluationSummary(evaluationSummary); Action <Tuple <DateTime, DateTime> > evaluatingAction = (Tuple <DateTime, DateTime> interval) => { if (_toBeStopped) { return; } // initialize data provider var dataProvider = new ChinaStockDataProvider( stockNameTable, allDataFiles, interval.Item1, // interval start date interval.Item2, // interval end date options.WarmupPeriods); var finalCodes = dataProvider.GetAllTradingObjects().Select(to => to.Code); var filteredStockBlockRelationshipManager = stockBlockRelationshipManager == null ? null : stockBlockRelationshipManager.CreateSubsetForStocks(finalCodes); // initialize combined strategy assembler var combinedStrategyAssembler = new CombinedStrategyAssembler(combinedStrategySettings, true); var strategyInstances = new List <Tuple <CombinedStrategy, IDictionary <ParameterAttribute, object> > >(); IDictionary <ParameterAttribute, object> values; while ((values = combinedStrategyAssembler.GetNextSetOfParameterValues()) != null) { var strategy = combinedStrategyAssembler.NewStrategy(); strategyInstances.Add(Tuple.Create(strategy, values)); } if (strategyInstances.Any()) { // initialize ResultSummary ResultSummary.Initialize(strategyInstances.First().Item2, options.EnableERatioOutput); } SetTotalStrategyNumber(intervals.Count() * strategyInstances.Count()); try { Parallel.For( 0, strategyInstances.Count, // below line is for performance profiling only. new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount * 2 }, t => { for (int i = 0; i < options.AccountNumber; ++i) { if (_toBeStopped) { return; } ICapitalManager capitalManager = options.ProportionOfCapitalForIncrementalPosition > 0.0 ? (ICapitalManager) new AdvancedCapitalManager(options.InitialCapital, options.ProportionOfCapitalForIncrementalPosition) : (ICapitalManager) new SimpleCapitalManager(options.InitialCapital) ; EvaluateStrategy( options.AccountNumber, i, _contextManager, strategyInstances[t].Item1, strategyInstances[t].Item2, interval.Item1, interval.Item2, capitalManager, dataProvider, filteredStockBlockRelationshipManager, options.ShouldDumpData, tradingSettings); } IncreaseProgress(); // reset the strategy object to ensure the referred IEvaluationContext object being // released, otherwise it will never be released until all strategies are evaluated. // This is a bug hid for long time. strategyInstances[t] = null; }); } catch { _toBeStopped = true; } finally { lock (_contextManager) { // save result summary _contextManager.SaveResultSummaries(); } } }; if (options.ParallelExecution) { Parallel.ForEach(intervals, evaluatingAction); } else { foreach (var interval in intervals) { evaluatingAction(interval); } } } _contextManager = null; Console.WriteLine(); Console.WriteLine("Done."); }