public TradingStrategyEvaluator(
            int numberOfAccounts,
            int accountId,
            ICapitalManager capitalManager,
            ITradingStrategy strategy,
            IDictionary <ParameterAttribute, object> strategyParameters,
            ITradingDataProvider provider,
            StockBlockRelationshipManager relationshipManager,
            TradingSettings settings,
            ILogger logger,
            StreamWriter dumpDataWriter)
        {
            if (numberOfAccounts <= 0 || accountId < 0 || accountId >= numberOfAccounts)
            {
                throw new ArgumentOutOfRangeException();
            }

            if (strategy == null || provider == null || settings == null)
            {
                throw new ArgumentNullException();
            }

            _numberOfAccounts        = numberOfAccounts;
            _accountId               = accountId;
            _strategy                = strategy;
            _strategyParameterValues = strategyParameters;

            _provider = provider;

            _settings = settings;

            _equityManager  = new EquityManager(capitalManager, _settings.PositionFrozenDays);
            _context        = new StandardEvaluationContext(_provider, _equityManager, logger, settings, dumpDataWriter, relationshipManager);
            _tradingTracker = new TradingTracker(capitalManager.InitialCapital);
        }
        public TradingStrategyPredicator(
            double initialCapital,
            double currentCapital,
            ITradingStrategy strategy,
            IDictionary <ParameterAttribute, object> strategyParameters,
            ITradingDataProvider provider,
            StockBlockRelationshipManager relationshipManager,
            int positionFrozenDays,
            IEnumerable <Position> activePositions,
            ILogger logger)
        {
            if (strategy == null || provider == null)
            {
                throw new ArgumentNullException();
            }

            _strategy = strategy;
            _strategyParameterValues = strategyParameters;

            _provider = provider;

            _equityManager = new EquityManager(new SimpleCapitalManager(initialCapital, currentCapital), positionFrozenDays);
            _unprocessedActivePositions = activePositions.ToList();

            _context = new StandardEvaluationContext(_provider, _equityManager, logger, null, null, relationshipManager);
        }
Example #3
0
        static IEnumerable <string> SelectStockAndFilterBlocks(ref StockBlockRelationshipManager manager, int minStockPerBlock)
        {
            var stocks = manager.FindMinimumStockSetCoveredAllBlocks(minStockPerBlock);

            manager = manager.CreateSubsetForStocks(stocks);

            return(stocks);
        }
        public StandardEvaluationContext(
            ITradingDataProvider provider,
            EquityManager equityManager,
            ILogger logger,
            TradingSettings settings    = null,
            StreamWriter dumpDataWriter = null,
            StockBlockRelationshipManager relationshipManager = null)
        {
            if (equityManager == null || provider == null || logger == null)
            {
                throw new ArgumentNullException();
            }

            _provider      = provider;
            _equityManager = equityManager;
            _logger        = logger;
            _settings      = settings;

            _relationshipManager = relationshipManager;

            var metricManager      = new StandardRuntimeMetricManager(_provider.GetAllTradingObjects().Length);
            var groupMetricManager = new StandardGroupRuntimeMetricManager(metricManager);

            // register the group metric manager as observer of metric manager.
            metricManager.RegisterAfterUpdatedMetricsObserver(groupMetricManager);

            _metricManager      = metricManager;
            _groupMetricManager = groupMetricManager;

            _boardIndexTradingObjects = new Dictionary <string, ITradingObject>();

            var boards = new StockBoard[]
            {
                StockBoard.GrowingBoard,
                StockBoard.MainBoard,
                StockBoard.SmallMiddleBoard
            };

            foreach (var board in boards)
            {
                string         boardIndex    = StockName.GetBoardIndex(board);
                ITradingObject tradingObject = GetTradingObject(boardIndex);
                _boardIndexTradingObjects.Add(boardIndex, tradingObject);
            }

            _dumper = dumpDataWriter == null ? null : new StreamDataDumper(dumpDataWriter, 8, 3, _settings.DumpMetrics, this, _provider);
        }
Example #5
0
        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);
                }
            }
        }
Example #6
0
        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.");
        }
Example #7
0
        private static void PredicateStrategy(
            PredicationContext context,
            ITradingStrategy strategy,
            IDictionary <ParameterAttribute, object> parameterValues,
            DateTime startDate,
            double initialCapital,
            double currentCapital,
            IEnumerable <Position> activePositions,
            ITradingDataProvider dataProvider,
            StockBlockRelationshipManager relationshipManager,
            int positionFrozenDays)
        {
            var predicator = new TradingStrategyPredicator(
                initialCapital,
                currentCapital,
                strategy,
                parameterValues,
                dataProvider,
                relationshipManager,
                positionFrozenDays,
                activePositions,
                context.Logger);

            try
            {
                predicator.Predicate();

                var auxiliaryData = predicator.PredicatedTransactions
                                    .Select(
                    transaction =>
                {
                    var codeIndex = dataProvider.GetIndexOfTradingObject(transaction.Code);
                    Bar lastBar;

                    if (!dataProvider.GetLastEffectiveBar(codeIndex, transaction.SubmissionTime, out lastBar))
                    {
                        lastBar.OpenPrice    = 0.0;
                        lastBar.HighestPrice = 0.0;
                        lastBar.LowestPrice  = 0.0;
                        lastBar.ClosePrice   = 0.0;
                    }

                    return(new AuxiliaryData()
                    {
                        Code = transaction.Code,
                        Name = transaction.Name,
                        OpenPrice = lastBar.OpenPrice,
                        ClosePrice = lastBar.ClosePrice,
                        HighestPrice = lastBar.HighestPrice,
                        LowestPrice = lastBar.LowestPrice
                    });
                });

                context.SaveResults(
                    dataProvider,
                    parameterValues,
                    predicator.ActivePositions,
                    predicator.PredicatedTransactions,
                    auxiliaryData);
            }
            catch (Exception ex)
            {
                Console.WriteLine();
                Console.WriteLine("{0}", ex);
                return;
            }
        }
Example #8
0
        static void Run(Options options)
        {
            // check the validation of options
            CheckOptions(options);

            // load settings from files
            var combinedStrategySettings = CombinedStrategySettings.LoadFromFile(options.CombinedStrategySettingsFile);
            var stockDataSettings        = ChinaStockDataSettings.LoadFromFile(options.StockDataSettingsFile);
            var positions = LoadPositions(options.PositionFile);

            // 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();

            // initialize data provider
            var dataProvider
                = new ChinaStockDataProvider(
                      stockNameTable,
                      allDataFiles,
                      options.StartDate,
                      options.EndDate,
                      options.WarmupPeriods);

            var finalCodes = dataProvider.GetAllTradingObjects().Select(to => to.Code);
            var filteredStockBlockRelationshipManager = stockBlockRelationshipManager == null
                ? null
                : stockBlockRelationshipManager.CreateSubsetForStocks(finalCodes);

            if (filteredStockBlockRelationshipManager != null)
            {
                var filteredCodes = filteredStockBlockRelationshipManager.Stocks;

                var filteredDataFiles = filteredCodes
                                        .Select(stockDataSettings.BuildActualDataFilePathAndName)
                                        .ToArray();

                // rebuild data provider according to filtered codes
                dataProvider = new ChinaStockDataProvider(
                    stockNameTable,
                    filteredDataFiles,
                    options.StartDate,
                    options.EndDate,
                    options.WarmupPeriods);
            }

            // initialize combined strategy assembler
            var combinedStrategyAssembler = new CombinedStrategyAssembler(combinedStrategySettings, false);

            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.Count != 1)
            {
                throw new InvalidDataException("Strategy has more or less than one instance, please check strategy settings");
            }

            string predictionContextDirectory = options.PredicationName + "_" + DateTime.Now.ToString("yyyyMMddTHHmmss");

            if (!Directory.Exists(predictionContextDirectory))
            {
                Directory.CreateDirectory(predictionContextDirectory);
            }

            using (PredicationContext context = new PredicationContext(predictionContextDirectory))
            {
                PredicateStrategy(
                    context,
                    strategyInstances.First().Item1,
                    strategyInstances.First().Item2,
                    options.StartDate,
                    options.InitialCapital,
                    options.CurrentCapital,
                    positions,
                    dataProvider,
                    filteredStockBlockRelationshipManager,
                    options.PositionFrozenDays);
            }

            Console.WriteLine();
            Console.WriteLine("Done.");
        }